github.com/netdata/go.d.plugin@v0.58.1/modules/mysql/charts.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package mysql
     4  
     5  import (
     6  	"fmt"
     7  	"strings"
     8  
     9  	"github.com/netdata/go.d.plugin/agent/module"
    10  )
    11  
    12  const (
    13  	prioBandwidth = module.Priority + iota
    14  	prioQueries
    15  	prioQueriesType
    16  	prioHandlers
    17  	prioTableOpenCacheOverflows
    18  	prioTableLocks
    19  	prioTableJoinIssues
    20  	prioTableSortIssues
    21  	prioTmpOperations
    22  	prioConnections
    23  	prioActiveConnections
    24  	prioBinlogCache
    25  	prioBinlogStatementCache
    26  	prioThreads
    27  	prioThreadsCreated
    28  	prioThreadCacheMisses
    29  	prioInnoDBIO
    30  	prioInnoDBIOOperations
    31  	prioInnoDBIOPendingOperations
    32  	prioInnoDBLog
    33  	prioInnoDBOSLog
    34  	prioInnoDBOSLogFsyncWrites
    35  	prioInnoDBOSLogIO
    36  	prioInnoDBCurRowLock
    37  	prioInnoDBRows
    38  	prioInnoDBBufferPoolPages
    39  	prioInnoDBBufferPoolPagesFlushed
    40  	prioInnoDBBufferPoolBytes
    41  	prioInnoDBBufferPoolReadAhead
    42  	prioInnoDBBufferPoolReadAheadRnd
    43  	prioInnoDBBufferPoolOperations
    44  	prioMyISAMKeyBlocks
    45  	prioMyISAMKeyRequests
    46  	prioMyISAMKeyDiskOperations
    47  	prioOpenFiles
    48  	prioOpenFilesRate
    49  	prioConnectionErrors
    50  	prioOpenedTables
    51  	prioOpenTables
    52  	prioProcessListFetchQueryDuration
    53  	prioProcessListQueries
    54  	prioProcessListLongestQueryDuration
    55  	prioInnoDBDeadlocks
    56  	prioQCacheOperations
    57  	prioQCacheQueries
    58  	prioQCacheFreeMem
    59  	prioQCacheMemBlocks
    60  	prioGaleraWriteSets
    61  	prioGaleraBytes
    62  	prioGaleraQueue
    63  	prioGaleraConflicts
    64  	prioGaleraFlowControl
    65  	prioGaleraClusterStatus
    66  	prioGaleraClusterState
    67  	prioGaleraClusterSize
    68  	prioGaleraClusterWeight
    69  	prioGaleraClusterConnectionStatus
    70  	prioGaleraReadinessState
    71  	prioGaleraOpenTransactions
    72  	prioGaleraThreadCount
    73  	prioSlaveSecondsBehindMaster
    74  	prioSlaveSQLIOThreadRunningState
    75  	prioUserStatsCPUTime
    76  	prioUserStatsRows
    77  	prioUserStatsCommands
    78  	prioUserStatsDeniedCommands
    79  	prioUserStatsTransactions
    80  	prioUserStatsBinlogWritten
    81  	prioUserStatsEmptyQueries
    82  	prioUserStatsConnections
    83  	prioUserStatsLostConnections
    84  	prioUserStatsDeniedConnections
    85  )
    86  
    87  var baseCharts = module.Charts{
    88  	chartBandwidth.Copy(),
    89  	chartQueries.Copy(),
    90  	chartQueriesType.Copy(),
    91  	chartHandlers.Copy(),
    92  	chartTableLocks.Copy(),
    93  	chartTableJoinIssues.Copy(),
    94  	chartTableSortIssues.Copy(),
    95  	chartTmpOperations.Copy(),
    96  	chartConnections.Copy(),
    97  	chartActiveConnections.Copy(),
    98  	chartThreads.Copy(),
    99  	chartThreadCreationRate.Copy(),
   100  	chartThreadsCacheMisses.Copy(),
   101  	chartInnoDBIO.Copy(),
   102  	chartInnoDBIOOperations.Copy(),
   103  	chartInnoDBPendingIOOperations.Copy(),
   104  	chartInnoDBLogOperations.Copy(),
   105  	chartInnoDBCurrentRowLocks.Copy(),
   106  	chartInnoDBRowsOperations.Copy(),
   107  	chartInnoDBBufferPoolPages.Copy(),
   108  	chartInnoDBBufferPoolPagesFlushed.Copy(),
   109  	chartInnoDBBufferPoolBytes.Copy(),
   110  	chartInnoDBBufferPoolReadAhead.Copy(),
   111  	chartInnoDBBufferPoolReadAheadRnd.Copy(),
   112  	chartInnoDBBufferPoolOperations.Copy(),
   113  	chartOpenFiles.Copy(),
   114  	chartOpenedFilesRate.Copy(),
   115  	chartConnectionErrors.Copy(),
   116  	chartOpenedTables.Copy(),
   117  	chartOpenTables.Copy(),
   118  	chartProcessListFetchQueryDuration.Copy(),
   119  	chartProcessListQueries.Copy(),
   120  	chartProcessListLongestQueryDuration.Copy(),
   121  }
   122  
   123  var (
   124  	chartBandwidth = module.Chart{
   125  		ID:       "net",
   126  		Title:    "Bandwidth",
   127  		Units:    "kilobits/s",
   128  		Fam:      "bandwidth",
   129  		Ctx:      "mysql.net",
   130  		Type:     module.Area,
   131  		Priority: prioBandwidth,
   132  		Dims: module.Dims{
   133  			{ID: "bytes_received", Name: "in", Algo: module.Incremental, Mul: 8, Div: 1000},
   134  			{ID: "bytes_sent", Name: "out", Algo: module.Incremental, Mul: -8, Div: 1000},
   135  		},
   136  	}
   137  	chartQueries = module.Chart{
   138  		ID:       "queries",
   139  		Title:    "Queries",
   140  		Units:    "queries/s",
   141  		Fam:      "queries",
   142  		Ctx:      "mysql.queries",
   143  		Priority: prioQueries,
   144  		Dims: module.Dims{
   145  			{ID: "queries", Name: "queries", Algo: module.Incremental},
   146  			{ID: "questions", Name: "questions", Algo: module.Incremental},
   147  			{ID: "slow_queries", Name: "slow_queries", Algo: module.Incremental},
   148  		},
   149  	}
   150  	chartQueriesType = module.Chart{
   151  		ID:       "queries_type",
   152  		Title:    "Queries By Type",
   153  		Units:    "queries/s",
   154  		Fam:      "queries",
   155  		Ctx:      "mysql.queries_type",
   156  		Type:     module.Stacked,
   157  		Priority: prioQueriesType,
   158  		Dims: module.Dims{
   159  			{ID: "com_select", Name: "select", Algo: module.Incremental},
   160  			{ID: "com_delete", Name: "delete", Algo: module.Incremental},
   161  			{ID: "com_update", Name: "update", Algo: module.Incremental},
   162  			{ID: "com_insert", Name: "insert", Algo: module.Incremental},
   163  			{ID: "com_replace", Name: "replace", Algo: module.Incremental},
   164  		},
   165  	}
   166  	chartHandlers = module.Chart{
   167  		ID:       "handlers",
   168  		Title:    "Handlers",
   169  		Units:    "handlers/s",
   170  		Fam:      "handlers",
   171  		Ctx:      "mysql.handlers",
   172  		Priority: prioHandlers,
   173  		Dims: module.Dims{
   174  			{ID: "handler_commit", Name: "commit", Algo: module.Incremental},
   175  			{ID: "handler_delete", Name: "delete", Algo: module.Incremental},
   176  			{ID: "handler_prepare", Name: "prepare", Algo: module.Incremental},
   177  			{ID: "handler_read_first", Name: "read first", Algo: module.Incremental},
   178  			{ID: "handler_read_key", Name: "read key", Algo: module.Incremental},
   179  			{ID: "handler_read_next", Name: "read next", Algo: module.Incremental},
   180  			{ID: "handler_read_prev", Name: "read prev", Algo: module.Incremental},
   181  			{ID: "handler_read_rnd", Name: "read rnd", Algo: module.Incremental},
   182  			{ID: "handler_read_rnd_next", Name: "read rnd next", Algo: module.Incremental},
   183  			{ID: "handler_rollback", Name: "rollback", Algo: module.Incremental},
   184  			{ID: "handler_savepoint", Name: "savepoint", Algo: module.Incremental},
   185  			{ID: "handler_savepoint_rollback", Name: "savepointrollback", Algo: module.Incremental},
   186  			{ID: "handler_update", Name: "update", Algo: module.Incremental},
   187  			{ID: "handler_write", Name: "write", Algo: module.Incremental},
   188  		},
   189  	}
   190  	chartTableOpenCacheOverflows = module.Chart{
   191  		ID:       "table_open_cache_overflows",
   192  		Title:    "Table open cache overflows",
   193  		Units:    "overflows/s",
   194  		Fam:      "open cache",
   195  		Ctx:      "mysql.table_open_cache_overflows",
   196  		Priority: prioTableOpenCacheOverflows,
   197  		Dims: module.Dims{
   198  			{ID: "table_open_cache_overflows", Name: "open_cache", Algo: module.Incremental},
   199  		},
   200  	}
   201  	chartTableLocks = module.Chart{
   202  		ID:       "table_locks",
   203  		Title:    "Table Locks",
   204  		Units:    "locks/s",
   205  		Fam:      "locks",
   206  		Ctx:      "mysql.table_locks",
   207  		Priority: prioTableLocks,
   208  		Dims: module.Dims{
   209  			{ID: "table_locks_immediate", Name: "immediate", Algo: module.Incremental},
   210  			{ID: "table_locks_waited", Name: "waited", Algo: module.Incremental, Mul: -1},
   211  		},
   212  	}
   213  	chartTableJoinIssues = module.Chart{
   214  		ID:       "join_issues",
   215  		Title:    "Table Select Join Issues",
   216  		Units:    "joins/s",
   217  		Fam:      "issues",
   218  		Ctx:      "mysql.join_issues",
   219  		Priority: prioTableJoinIssues,
   220  		Dims: module.Dims{
   221  			{ID: "select_full_join", Name: "full join", Algo: module.Incremental},
   222  			{ID: "select_full_range_join", Name: "full range join", Algo: module.Incremental},
   223  			{ID: "select_range", Name: "range", Algo: module.Incremental},
   224  			{ID: "select_range_check", Name: "range check", Algo: module.Incremental},
   225  			{ID: "select_scan", Name: "scan", Algo: module.Incremental},
   226  		},
   227  	}
   228  	chartTableSortIssues = module.Chart{
   229  		ID:       "sort_issues",
   230  		Title:    "Table Sort Issues",
   231  		Units:    "issues/s",
   232  		Fam:      "issues",
   233  		Ctx:      "mysql.sort_issues",
   234  		Priority: prioTableSortIssues,
   235  		Dims: module.Dims{
   236  			{ID: "sort_merge_passes", Name: "merge passes", Algo: module.Incremental},
   237  			{ID: "sort_range", Name: "range", Algo: module.Incremental},
   238  			{ID: "sort_scan", Name: "scan", Algo: module.Incremental},
   239  		},
   240  	}
   241  	chartTmpOperations = module.Chart{
   242  		ID:       "tmp",
   243  		Title:    "Tmp Operations",
   244  		Units:    "events/s",
   245  		Fam:      "temporaries",
   246  		Ctx:      "mysql.tmp",
   247  		Priority: prioTmpOperations,
   248  		Dims: module.Dims{
   249  			{ID: "created_tmp_disk_tables", Name: "disk tables", Algo: module.Incremental},
   250  			{ID: "created_tmp_files", Name: "files", Algo: module.Incremental},
   251  			{ID: "created_tmp_tables", Name: "tables", Algo: module.Incremental},
   252  		},
   253  	}
   254  	chartConnections = module.Chart{
   255  		ID:       "connections",
   256  		Title:    "Connections",
   257  		Units:    "connections/s",
   258  		Fam:      "connections",
   259  		Ctx:      "mysql.connections",
   260  		Priority: prioConnections,
   261  		Dims: module.Dims{
   262  			{ID: "connections", Name: "all", Algo: module.Incremental},
   263  			{ID: "aborted_connects", Name: "aborted", Algo: module.Incremental},
   264  		},
   265  	}
   266  	chartActiveConnections = module.Chart{
   267  		ID:       "connections_active",
   268  		Title:    "Active Connections",
   269  		Units:    "connections",
   270  		Fam:      "connections",
   271  		Ctx:      "mysql.connections_active",
   272  		Priority: prioActiveConnections,
   273  		Dims: module.Dims{
   274  			{ID: "threads_connected", Name: "active"},
   275  			{ID: "max_connections", Name: "limit"},
   276  			{ID: "max_used_connections", Name: "max active"},
   277  		},
   278  	}
   279  	chartThreads = module.Chart{
   280  		ID:       "threads",
   281  		Title:    "Threads",
   282  		Units:    "threads",
   283  		Fam:      "threads",
   284  		Ctx:      "mysql.threads",
   285  		Priority: prioThreads,
   286  		Dims: module.Dims{
   287  			{ID: "threads_connected", Name: "connected"},
   288  			{ID: "threads_cached", Name: "cached", Mul: -1},
   289  			{ID: "threads_running", Name: "running"},
   290  		},
   291  	}
   292  	chartThreadCreationRate = module.Chart{
   293  		ID:       "threads_creation_rate",
   294  		Title:    "Threads Creation Rate",
   295  		Units:    "threads/s",
   296  		Fam:      "threads",
   297  		Ctx:      "mysql.threads_created",
   298  		Priority: prioThreadsCreated,
   299  		Dims: module.Dims{
   300  			{ID: "threads_created", Name: "created", Algo: module.Incremental},
   301  		},
   302  	}
   303  	chartThreadsCacheMisses = module.Chart{
   304  		ID:       "thread_cache_misses",
   305  		Title:    "Threads Cache Misses",
   306  		Units:    "misses",
   307  		Fam:      "threads",
   308  		Ctx:      "mysql.thread_cache_misses",
   309  		Type:     module.Area,
   310  		Priority: prioThreadCacheMisses,
   311  		Dims: module.Dims{
   312  			{ID: "thread_cache_misses", Name: "misses", Div: 100},
   313  		},
   314  	}
   315  	chartInnoDBIO = module.Chart{
   316  		ID:       "innodb_io",
   317  		Title:    "InnoDB I/O Bandwidth",
   318  		Units:    "KiB/s",
   319  		Fam:      "innodb",
   320  		Ctx:      "mysql.innodb_io",
   321  		Type:     module.Area,
   322  		Priority: prioInnoDBIO,
   323  		Dims: module.Dims{
   324  			{ID: "innodb_data_read", Name: "read", Algo: module.Incremental, Div: 1024},
   325  			{ID: "innodb_data_written", Name: "write", Algo: module.Incremental, Div: 1024},
   326  		},
   327  	}
   328  	chartInnoDBIOOperations = module.Chart{
   329  		ID:       "innodb_io_ops",
   330  		Title:    "InnoDB I/O Operations",
   331  		Units:    "operations/s",
   332  		Fam:      "innodb",
   333  		Ctx:      "mysql.innodb_io_ops",
   334  		Priority: prioInnoDBIOOperations,
   335  		Dims: module.Dims{
   336  			{ID: "innodb_data_reads", Name: "reads", Algo: module.Incremental},
   337  			{ID: "innodb_data_writes", Name: "writes", Algo: module.Incremental, Mul: -1},
   338  			{ID: "innodb_data_fsyncs", Name: "fsyncs", Algo: module.Incremental},
   339  		},
   340  	}
   341  	chartInnoDBPendingIOOperations = module.Chart{
   342  		ID:       "innodb_io_pending_ops",
   343  		Title:    "InnoDB Pending I/O Operations",
   344  		Units:    "operations",
   345  		Fam:      "innodb",
   346  		Ctx:      "mysql.innodb_io_pending_ops",
   347  		Priority: prioInnoDBIOPendingOperations,
   348  		Dims: module.Dims{
   349  			{ID: "innodb_data_pending_reads", Name: "reads"},
   350  			{ID: "innodb_data_pending_writes", Name: "writes", Mul: -1},
   351  			{ID: "innodb_data_pending_fsyncs", Name: "fsyncs"},
   352  		},
   353  	}
   354  	chartInnoDBLogOperations = module.Chart{
   355  		ID:       "innodb_log",
   356  		Title:    "InnoDB Log Operations",
   357  		Units:    "operations/s",
   358  		Fam:      "innodb",
   359  		Ctx:      "mysql.innodb_log",
   360  		Priority: prioInnoDBLog,
   361  		Dims: module.Dims{
   362  			{ID: "innodb_log_waits", Name: "waits", Algo: module.Incremental},
   363  			{ID: "innodb_log_write_requests", Name: "write requests", Algo: module.Incremental, Mul: -1},
   364  			{ID: "innodb_log_writes", Name: "writes", Algo: module.Incremental, Mul: -1},
   365  		},
   366  	}
   367  	chartInnoDBCurrentRowLocks = module.Chart{
   368  		ID:       "innodb_cur_row_lock",
   369  		Title:    "InnoDB Current Row Locks",
   370  		Units:    "operations",
   371  		Fam:      "innodb",
   372  		Ctx:      "mysql.innodb_cur_row_lock",
   373  		Type:     module.Area,
   374  		Priority: prioInnoDBCurRowLock,
   375  		Dims: module.Dims{
   376  			{ID: "innodb_row_lock_current_waits", Name: "current waits"},
   377  		},
   378  	}
   379  	chartInnoDBRowsOperations = module.Chart{
   380  		ID:       "innodb_rows",
   381  		Title:    "InnoDB Row Operations",
   382  		Units:    "operations/s",
   383  		Fam:      "innodb",
   384  		Ctx:      "mysql.innodb_rows",
   385  		Type:     module.Area,
   386  		Priority: prioInnoDBRows,
   387  		Dims: module.Dims{
   388  			{ID: "innodb_rows_inserted", Name: "inserted", Algo: module.Incremental},
   389  			{ID: "innodb_rows_read", Name: "read", Algo: module.Incremental},
   390  			{ID: "innodb_rows_updated", Name: "updated", Algo: module.Incremental},
   391  			{ID: "innodb_rows_deleted", Name: "deleted", Algo: module.Incremental, Mul: -1},
   392  		},
   393  	}
   394  	chartInnoDBBufferPoolPages = module.Chart{
   395  		ID:       "innodb_buffer_pool_pages",
   396  		Title:    "InnoDB Buffer Pool Pages",
   397  		Units:    "pages",
   398  		Fam:      "innodb",
   399  		Ctx:      "mysql.innodb_buffer_pool_pages",
   400  		Priority: prioInnoDBBufferPoolPages,
   401  		Dims: module.Dims{
   402  			{ID: "innodb_buffer_pool_pages_data", Name: "data"},
   403  			{ID: "innodb_buffer_pool_pages_dirty", Name: "dirty", Mul: -1},
   404  			{ID: "innodb_buffer_pool_pages_free", Name: "free"},
   405  			{ID: "innodb_buffer_pool_pages_misc", Name: "misc", Mul: -1},
   406  			{ID: "innodb_buffer_pool_pages_total", Name: "total"},
   407  		},
   408  	}
   409  	chartInnoDBBufferPoolPagesFlushed = module.Chart{
   410  		ID:       "innodb_buffer_pool_flush_pages_requests",
   411  		Title:    "InnoDB Buffer Pool Flush Pages Requests",
   412  		Units:    "requests/s",
   413  		Fam:      "innodb",
   414  		Ctx:      "mysql.innodb_buffer_pool_pages_flushed",
   415  		Priority: prioInnoDBBufferPoolPagesFlushed,
   416  		Dims: module.Dims{
   417  			{ID: "innodb_buffer_pool_pages_flushed", Name: "flush pages", Algo: module.Incremental},
   418  		},
   419  	}
   420  	chartInnoDBBufferPoolBytes = module.Chart{
   421  		ID:       "innodb_buffer_pool_bytes",
   422  		Title:    "InnoDB Buffer Pool Bytes",
   423  		Units:    "MiB",
   424  		Fam:      "innodb",
   425  		Ctx:      "mysql.innodb_buffer_pool_bytes",
   426  		Type:     module.Area,
   427  		Priority: prioInnoDBBufferPoolBytes,
   428  		Dims: module.Dims{
   429  			{ID: "innodb_buffer_pool_bytes_data", Name: "data", Div: 1024 * 1024},
   430  			{ID: "innodb_buffer_pool_bytes_dirty", Name: "dirty", Mul: -1, Div: 1024 * 1024},
   431  		},
   432  	}
   433  	chartInnoDBBufferPoolReadAhead = module.Chart{
   434  		ID:       "innodb_buffer_pool_read_ahead",
   435  		Title:    "InnoDB Buffer Pool Read Pages",
   436  		Units:    "pages/s",
   437  		Fam:      "innodb",
   438  		Ctx:      "mysql.innodb_buffer_pool_read_ahead",
   439  		Type:     module.Area,
   440  		Priority: prioInnoDBBufferPoolReadAhead,
   441  		Dims: module.Dims{
   442  			{ID: "innodb_buffer_pool_read_ahead", Name: "all", Algo: module.Incremental},
   443  			{ID: "innodb_buffer_pool_read_ahead_evicted", Name: "evicted", Algo: module.Incremental, Mul: -1},
   444  		},
   445  	}
   446  	chartInnoDBBufferPoolReadAheadRnd = module.Chart{
   447  		ID:       "innodb_buffer_pool_read_ahead_rnd",
   448  		Title:    "InnoDB Buffer Pool Random Read-Aheads",
   449  		Units:    "operations/s",
   450  		Fam:      "innodb",
   451  		Ctx:      "mysql.innodb_buffer_pool_read_ahead_rnd",
   452  		Priority: prioInnoDBBufferPoolReadAheadRnd,
   453  		Dims: module.Dims{
   454  			{ID: "innodb_buffer_pool_read_ahead_rnd", Name: "read-ahead", Algo: module.Incremental},
   455  		},
   456  	}
   457  	chartInnoDBBufferPoolOperations = module.Chart{
   458  		ID:       "innodb_buffer_pool_ops",
   459  		Title:    "InnoDB Buffer Pool Operations",
   460  		Units:    "operations/s",
   461  		Fam:      "innodb",
   462  		Ctx:      "mysql.innodb_buffer_pool_ops",
   463  		Type:     module.Area,
   464  		Priority: prioInnoDBBufferPoolOperations,
   465  		Dims: module.Dims{
   466  			{ID: "innodb_buffer_pool_reads", Name: "disk reads", Algo: module.Incremental},
   467  			{ID: "innodb_buffer_pool_wait_free", Name: "wait free", Algo: module.Incremental, Mul: -1, Div: 1},
   468  		},
   469  	}
   470  	chartOpenFiles = module.Chart{
   471  		ID:       "files",
   472  		Title:    "Open Files",
   473  		Units:    "files",
   474  		Fam:      "files",
   475  		Ctx:      "mysql.files",
   476  		Priority: prioOpenFiles,
   477  		Dims: module.Dims{
   478  			{ID: "open_files", Name: "files"},
   479  		},
   480  	}
   481  	chartOpenedFilesRate = module.Chart{
   482  		ID:       "files_rate",
   483  		Title:    "Opened Files Rate",
   484  		Units:    "files/s",
   485  		Fam:      "files",
   486  		Ctx:      "mysql.files_rate",
   487  		Priority: prioOpenFilesRate,
   488  		Dims: module.Dims{
   489  			{ID: "opened_files", Name: "files", Algo: module.Incremental},
   490  		},
   491  	}
   492  	chartConnectionErrors = module.Chart{
   493  		ID:       "connection_errors",
   494  		Title:    "Connection Errors",
   495  		Units:    "errors/s",
   496  		Fam:      "connections",
   497  		Ctx:      "mysql.connection_errors",
   498  		Priority: prioConnectionErrors,
   499  		Dims: module.Dims{
   500  			{ID: "connection_errors_accept", Name: "accept", Algo: module.Incremental},
   501  			{ID: "connection_errors_internal", Name: "internal", Algo: module.Incremental},
   502  			{ID: "connection_errors_max_connections", Name: "max", Algo: module.Incremental},
   503  			{ID: "connection_errors_peer_address", Name: "peer addr", Algo: module.Incremental},
   504  			{ID: "connection_errors_select", Name: "select", Algo: module.Incremental},
   505  			{ID: "connection_errors_tcpwrap", Name: "tcpwrap", Algo: module.Incremental},
   506  		},
   507  	}
   508  	chartOpenedTables = module.Chart{
   509  		ID:       "opened_tables",
   510  		Title:    "Opened Tables",
   511  		Units:    "tables/s",
   512  		Fam:      "open tables",
   513  		Ctx:      "mysql.opened_tables",
   514  		Priority: prioOpenedTables,
   515  		Dims: module.Dims{
   516  			{ID: "opened_tables", Name: "tables", Algo: module.Incremental},
   517  		},
   518  	}
   519  	chartOpenTables = module.Chart{
   520  		ID:       "open_tables",
   521  		Title:    "Open Tables",
   522  		Units:    "tables",
   523  		Fam:      "open tables",
   524  		Ctx:      "mysql.open_tables",
   525  		Type:     module.Area,
   526  		Priority: prioOpenTables,
   527  		Dims: module.Dims{
   528  			{ID: "table_open_cache", Name: "cache"},
   529  			{ID: "open_tables", Name: "tables"},
   530  		},
   531  	}
   532  	chartProcessListFetchQueryDuration = module.Chart{
   533  		ID:       "process_list_fetch_duration",
   534  		Title:    "Process List Fetch Duration",
   535  		Units:    "milliseconds",
   536  		Fam:      "process list",
   537  		Ctx:      "mysql.process_list_fetch_query_duration",
   538  		Priority: prioProcessListFetchQueryDuration,
   539  		Dims: module.Dims{
   540  			{ID: "process_list_fetch_query_duration", Name: "duration"},
   541  		},
   542  	}
   543  	chartProcessListQueries = module.Chart{
   544  		ID:       "process_list_queries_count",
   545  		Title:    "Queries Count",
   546  		Units:    "queries",
   547  		Fam:      "process list",
   548  		Ctx:      "mysql.process_list_queries_count",
   549  		Type:     module.Stacked,
   550  		Priority: prioProcessListQueries,
   551  		Dims: module.Dims{
   552  			{ID: "process_list_queries_count_system", Name: "system"},
   553  			{ID: "process_list_queries_count_user", Name: "user"},
   554  		},
   555  	}
   556  	chartProcessListLongestQueryDuration = module.Chart{
   557  		ID:       "process_list_longest_query_duration",
   558  		Title:    "Longest Query Duration",
   559  		Units:    "seconds",
   560  		Fam:      "process list",
   561  		Ctx:      "mysql.process_list_longest_query_duration",
   562  		Priority: prioProcessListLongestQueryDuration,
   563  		Dims: module.Dims{
   564  			{ID: "process_list_longest_query_duration", Name: "duration"},
   565  		},
   566  	}
   567  )
   568  
   569  var chartsInnoDBOSLog = module.Charts{
   570  	chartInnoDBOSLogPendingOperations.Copy(),
   571  	chartInnoDBOSLogOperations.Copy(),
   572  	chartInnoDBOSLogIO.Copy(),
   573  }
   574  
   575  var (
   576  	chartInnoDBOSLogPendingOperations = module.Chart{
   577  		ID:       "innodb_os_log",
   578  		Title:    "InnoDB OS Log Pending Operations",
   579  		Units:    "operations",
   580  		Fam:      "innodb",
   581  		Ctx:      "mysql.innodb_os_log",
   582  		Priority: prioInnoDBOSLog,
   583  		Dims: module.Dims{
   584  			{ID: "innodb_os_log_pending_fsyncs", Name: "fsyncs"},
   585  			{ID: "innodb_os_log_pending_writes", Name: "writes", Mul: -1},
   586  		},
   587  	}
   588  	chartInnoDBOSLogOperations = module.Chart{
   589  		ID:       "innodb_os_log_fsync_writes",
   590  		Title:    "InnoDB OS Log Operations",
   591  		Units:    "operations/s",
   592  		Fam:      "innodb",
   593  		Ctx:      "mysql.innodb_os_log_fsync_writes",
   594  		Priority: prioInnoDBOSLogFsyncWrites,
   595  		Dims: module.Dims{
   596  			{ID: "innodb_os_log_fsyncs", Name: "fsyncs", Algo: module.Incremental},
   597  		},
   598  	}
   599  	chartInnoDBOSLogIO = module.Chart{
   600  		ID:       "innodb_os_log_io",
   601  		Title:    "InnoDB OS Log Bandwidth",
   602  		Units:    "KiB/s",
   603  		Fam:      "innodb",
   604  		Ctx:      "mysql.innodb_os_log_io",
   605  		Type:     module.Area,
   606  		Priority: prioInnoDBOSLogIO,
   607  		Dims: module.Dims{
   608  			{ID: "innodb_os_log_written", Name: "write", Algo: module.Incremental, Mul: -1, Div: 1024},
   609  		},
   610  	}
   611  )
   612  
   613  var chartInnoDBDeadlocks = module.Chart{
   614  	ID:       "innodb_deadlocks",
   615  	Title:    "InnoDB Deadlocks",
   616  	Units:    "operations/s",
   617  	Fam:      "innodb",
   618  	Ctx:      "mysql.innodb_deadlocks",
   619  	Type:     module.Area,
   620  	Priority: prioInnoDBDeadlocks,
   621  	Dims: module.Dims{
   622  		{ID: "innodb_deadlocks", Name: "deadlocks", Algo: module.Incremental},
   623  	},
   624  }
   625  
   626  var chartsQCache = module.Charts{
   627  	chartQCacheOperations.Copy(),
   628  	chartQCacheQueries.Copy(),
   629  	chartQCacheFreeMemory.Copy(),
   630  	chartQCacheMemoryBlocks.Copy(),
   631  }
   632  
   633  var (
   634  	chartQCacheOperations = module.Chart{
   635  		ID:       "qcache_ops",
   636  		Title:    "QCache Operations",
   637  		Units:    "queries/s",
   638  		Fam:      "qcache",
   639  		Ctx:      "mysql.qcache_ops",
   640  		Priority: prioQCacheOperations,
   641  		Dims: module.Dims{
   642  			{ID: "qcache_hits", Name: "hits", Algo: module.Incremental},
   643  			{ID: "qcache_lowmem_prunes", Name: "lowmem prunes", Algo: module.Incremental, Mul: -1},
   644  			{ID: "qcache_inserts", Name: "inserts", Algo: module.Incremental},
   645  			{ID: "qcache_not_cached", Name: "not cached", Algo: module.Incremental, Mul: -1},
   646  		},
   647  	}
   648  	chartQCacheQueries = module.Chart{
   649  		ID:       "qcache",
   650  		Title:    "QCache Queries in Cache",
   651  		Units:    "queries",
   652  		Fam:      "qcache",
   653  		Ctx:      "mysql.qcache",
   654  		Priority: prioQCacheQueries,
   655  		Dims: module.Dims{
   656  			{ID: "qcache_queries_in_cache", Name: "queries", Algo: module.Absolute},
   657  		},
   658  	}
   659  	chartQCacheFreeMemory = module.Chart{
   660  		ID:       "qcache_freemem",
   661  		Title:    "QCache Free Memory",
   662  		Units:    "MiB",
   663  		Fam:      "qcache",
   664  		Ctx:      "mysql.qcache_freemem",
   665  		Type:     module.Area,
   666  		Priority: prioQCacheFreeMem,
   667  		Dims: module.Dims{
   668  			{ID: "qcache_free_memory", Name: "free", Div: 1024 * 1024},
   669  		},
   670  	}
   671  	chartQCacheMemoryBlocks = module.Chart{
   672  		ID:       "qcache_memblocks",
   673  		Title:    "QCache Memory Blocks",
   674  		Units:    "blocks",
   675  		Fam:      "qcache",
   676  		Ctx:      "mysql.qcache_memblocks",
   677  		Priority: prioQCacheMemBlocks,
   678  		Dims: module.Dims{
   679  			{ID: "qcache_free_blocks", Name: "free"},
   680  			{ID: "qcache_total_blocks", Name: "total"},
   681  		},
   682  	}
   683  )
   684  
   685  var chartsGalera = module.Charts{
   686  	chartGaleraWriteSets.Copy(),
   687  	chartGaleraBytes.Copy(),
   688  	chartGaleraQueue.Copy(),
   689  	chartGaleraConflicts.Copy(),
   690  	chartGaleraFlowControl.Copy(),
   691  	chartGaleraClusterStatus.Copy(),
   692  	chartGaleraClusterState.Copy(),
   693  	chartGaleraClusterSize.Copy(),
   694  	chartGaleraClusterWeight.Copy(),
   695  	chartGaleraClusterConnectionStatus.Copy(),
   696  	chartGaleraReadinessState.Copy(),
   697  	chartGaleraOpenTransactions.Copy(),
   698  	chartGaleraThreads.Copy(),
   699  }
   700  var (
   701  	chartGaleraWriteSets = module.Chart{
   702  		ID:       "galera_writesets",
   703  		Title:    "Replicated Writesets",
   704  		Units:    "writesets/s",
   705  		Fam:      "galera",
   706  		Ctx:      "mysql.galera_writesets",
   707  		Priority: prioGaleraWriteSets,
   708  		Dims: module.Dims{
   709  			{ID: "wsrep_received", Name: "rx", Algo: module.Incremental},
   710  			{ID: "wsrep_replicated", Name: "tx", Algo: module.Incremental, Mul: -1},
   711  		},
   712  	}
   713  	chartGaleraBytes = module.Chart{
   714  		ID:       "galera_bytes",
   715  		Title:    "Replicated Bytes",
   716  		Units:    "KiB/s",
   717  		Fam:      "galera",
   718  		Ctx:      "mysql.galera_bytes",
   719  		Type:     module.Area,
   720  		Priority: prioGaleraBytes,
   721  		Dims: module.Dims{
   722  			{ID: "wsrep_received_bytes", Name: "rx", Algo: module.Incremental, Div: 1024},
   723  			{ID: "wsrep_replicated_bytes", Name: "tx", Algo: module.Incremental, Mul: -1, Div: 1024},
   724  		},
   725  	}
   726  	chartGaleraQueue = module.Chart{
   727  		ID:       "galera_queue",
   728  		Title:    "Galera Queue",
   729  		Units:    "writesets",
   730  		Fam:      "galera",
   731  		Ctx:      "mysql.galera_queue",
   732  		Priority: prioGaleraQueue,
   733  		Dims: module.Dims{
   734  			{ID: "wsrep_local_recv_queue", Name: "rx"},
   735  			{ID: "wsrep_local_send_queue", Name: "tx", Mul: -1},
   736  		},
   737  	}
   738  	chartGaleraConflicts = module.Chart{
   739  		ID:       "galera_conflicts",
   740  		Title:    "Replication Conflicts",
   741  		Units:    "transactions",
   742  		Fam:      "galera",
   743  		Ctx:      "mysql.galera_conflicts",
   744  		Type:     module.Area,
   745  		Priority: prioGaleraConflicts,
   746  		Dims: module.Dims{
   747  			{ID: "wsrep_local_bf_aborts", Name: "bf aborts", Algo: module.Incremental},
   748  			{ID: "wsrep_local_cert_failures", Name: "cert fails", Algo: module.Incremental, Mul: -1},
   749  		},
   750  	}
   751  	chartGaleraFlowControl = module.Chart{
   752  		ID:       "galera_flow_control",
   753  		Title:    "Flow Control",
   754  		Units:    "ms",
   755  		Fam:      "galera",
   756  		Ctx:      "mysql.galera_flow_control",
   757  		Type:     module.Area,
   758  		Priority: prioGaleraFlowControl,
   759  		Dims: module.Dims{
   760  			{ID: "wsrep_flow_control_paused_ns", Name: "paused", Algo: module.Incremental, Div: 1000000},
   761  		},
   762  	}
   763  	chartGaleraClusterStatus = module.Chart{
   764  		ID:       "galera_cluster_status",
   765  		Title:    "Cluster Component Status",
   766  		Units:    "status",
   767  		Fam:      "galera",
   768  		Ctx:      "mysql.galera_cluster_status",
   769  		Priority: prioGaleraClusterStatus,
   770  		Dims: module.Dims{
   771  			{ID: "wsrep_cluster_status_primary", Name: "primary"},
   772  			{ID: "wsrep_cluster_status_non_primary", Name: "non_primary"},
   773  			{ID: "wsrep_cluster_status_disconnected", Name: "disconnected"},
   774  		},
   775  	}
   776  	chartGaleraClusterState = module.Chart{
   777  		ID:       "galera_cluster_state",
   778  		Title:    "Cluster Component State",
   779  		Units:    "state",
   780  		Fam:      "galera",
   781  		Ctx:      "mysql.galera_cluster_state",
   782  		Priority: prioGaleraClusterState,
   783  		Dims: module.Dims{
   784  			{ID: "wsrep_local_state_undefined", Name: "undefined"},
   785  			{ID: "wsrep_local_state_joiner", Name: "joining"},
   786  			{ID: "wsrep_local_state_donor", Name: "donor"},
   787  			{ID: "wsrep_local_state_joined", Name: "joined"},
   788  			{ID: "wsrep_local_state_synced", Name: "synced"},
   789  			{ID: "wsrep_local_state_error", Name: "error"},
   790  		},
   791  	}
   792  	chartGaleraClusterSize = module.Chart{
   793  		ID:       "galera_cluster_size",
   794  		Title:    "Number of Nodes in the Cluster",
   795  		Units:    "nodes",
   796  		Fam:      "galera",
   797  		Ctx:      "mysql.galera_cluster_size",
   798  		Priority: prioGaleraClusterSize,
   799  		Dims: module.Dims{
   800  			{ID: "wsrep_cluster_size", Name: "nodes"},
   801  		},
   802  	}
   803  	chartGaleraClusterWeight = module.Chart{
   804  		ID:       "galera_cluster_weight",
   805  		Title:    "The Total Weight of the Current Members in the Cluster",
   806  		Units:    "weight",
   807  		Fam:      "galera",
   808  		Ctx:      "mysql.galera_cluster_weight",
   809  		Priority: prioGaleraClusterWeight,
   810  		Dims: module.Dims{
   811  			{ID: "wsrep_cluster_weight", Name: "weight"},
   812  		},
   813  	}
   814  	chartGaleraClusterConnectionStatus = module.Chart{
   815  		ID:       "galera_connected",
   816  		Title:    "Cluster Connection Status",
   817  		Units:    "boolean",
   818  		Fam:      "galera",
   819  		Ctx:      "mysql.galera_connected",
   820  		Priority: prioGaleraClusterConnectionStatus,
   821  		Dims: module.Dims{
   822  			{ID: "wsrep_connected", Name: "connected"},
   823  		},
   824  	}
   825  	chartGaleraReadinessState = module.Chart{
   826  		ID:       "galera_ready",
   827  		Title:    "Accept Queries Readiness Status",
   828  		Units:    "boolean",
   829  		Fam:      "galera",
   830  		Ctx:      "mysql.galera_ready",
   831  		Priority: prioGaleraReadinessState,
   832  		Dims: module.Dims{
   833  			{ID: "wsrep_ready", Name: "ready"},
   834  		},
   835  	}
   836  	chartGaleraOpenTransactions = module.Chart{
   837  		ID:       "galera_open_transactions",
   838  		Title:    "Open Transactions",
   839  		Units:    "transactions",
   840  		Fam:      "galera",
   841  		Ctx:      "mysql.galera_open_transactions",
   842  		Priority: prioGaleraOpenTransactions,
   843  		Dims: module.Dims{
   844  			{ID: "wsrep_open_transactions", Name: "open"},
   845  		},
   846  	}
   847  	chartGaleraThreads = module.Chart{
   848  		ID:       "galera_thread_count",
   849  		Title:    "Total Number of WSRep (applier/rollbacker) Threads",
   850  		Units:    "threads",
   851  		Fam:      "galera",
   852  		Ctx:      "mysql.galera_thread_count",
   853  		Priority: prioGaleraThreadCount,
   854  		Dims: module.Dims{
   855  			{ID: "wsrep_thread_count", Name: "threads"},
   856  		},
   857  	}
   858  )
   859  
   860  var chartsMyISAM = module.Charts{
   861  	chartMyISAMKeyCacheBlocks.Copy(),
   862  	chartMyISAMKeyCacheRequests.Copy(),
   863  	chartMyISAMKeyCacheDiskOperations.Copy(),
   864  }
   865  var (
   866  	chartMyISAMKeyCacheBlocks = module.Chart{
   867  		ID:       "key_blocks",
   868  		Title:    "MyISAM Key Cache Blocks",
   869  		Units:    "blocks",
   870  		Fam:      "myisam",
   871  		Ctx:      "mysql.key_blocks",
   872  		Priority: prioMyISAMKeyBlocks,
   873  		Dims: module.Dims{
   874  			{ID: "key_blocks_unused", Name: "unused"},
   875  			{ID: "key_blocks_used", Name: "used", Mul: -1},
   876  			{ID: "key_blocks_not_flushed", Name: "not flushed"},
   877  		},
   878  	}
   879  	chartMyISAMKeyCacheRequests = module.Chart{
   880  		ID:       "key_requests",
   881  		Title:    "MyISAM Key Cache Requests",
   882  		Units:    "requests/s",
   883  		Fam:      "myisam",
   884  		Ctx:      "mysql.key_requests",
   885  		Type:     module.Area,
   886  		Priority: prioMyISAMKeyRequests,
   887  		Dims: module.Dims{
   888  			{ID: "key_read_requests", Name: "reads", Algo: module.Incremental},
   889  			{ID: "key_write_requests", Name: "writes", Algo: module.Incremental, Mul: -1},
   890  		},
   891  	}
   892  	chartMyISAMKeyCacheDiskOperations = module.Chart{
   893  		ID:       "key_disk_ops",
   894  		Title:    "MyISAM Key Cache Disk Operations",
   895  		Units:    "operations/s",
   896  		Fam:      "myisam",
   897  		Ctx:      "mysql.key_disk_ops",
   898  		Priority: prioMyISAMKeyDiskOperations,
   899  		Type:     module.Area,
   900  		Dims: module.Dims{
   901  			{ID: "key_reads", Name: "reads", Algo: module.Incremental},
   902  			{ID: "key_writes", Name: "writes", Algo: module.Incremental, Mul: -1},
   903  		},
   904  	}
   905  )
   906  
   907  var chartsBinlog = module.Charts{
   908  	chartBinlogCache.Copy(),
   909  	chartBinlogStatementCache.Copy(),
   910  }
   911  
   912  var (
   913  	chartBinlogCache = module.Chart{
   914  		ID:       "binlog_cache",
   915  		Title:    "Binlog Cache",
   916  		Units:    "transactions/s",
   917  		Fam:      "binlog",
   918  		Ctx:      "mysql.binlog_cache",
   919  		Priority: prioBinlogCache,
   920  		Dims: module.Dims{
   921  			{ID: "binlog_cache_disk_use", Name: "disk", Algo: module.Incremental},
   922  			{ID: "binlog_cache_use", Name: "all", Algo: module.Incremental},
   923  		},
   924  	}
   925  	chartBinlogStatementCache = module.Chart{
   926  		ID:       "binlog_stmt_cache",
   927  		Title:    "Binlog Statement Cache",
   928  		Units:    "statements/s",
   929  		Fam:      "binlog",
   930  		Ctx:      "mysql.binlog_stmt_cache",
   931  		Priority: prioBinlogStatementCache,
   932  		Dims: module.Dims{
   933  			{ID: "binlog_stmt_cache_disk_use", Name: "disk", Algo: module.Incremental},
   934  			{ID: "binlog_stmt_cache_use", Name: "all", Algo: module.Incremental},
   935  		},
   936  	}
   937  )
   938  
   939  var (
   940  	chartsSlaveReplication = module.Charts{
   941  		chartSlaveBehindSeconds.Copy(),
   942  		chartSlaveSQLIOThreadRunningState.Copy(),
   943  	}
   944  
   945  	chartSlaveBehindSeconds = module.Chart{
   946  		ID:       "slave_behind",
   947  		Title:    "Slave Behind Seconds",
   948  		Units:    "seconds",
   949  		Fam:      "slave",
   950  		Ctx:      "mysql.slave_behind",
   951  		Priority: prioSlaveSecondsBehindMaster,
   952  		Dims: module.Dims{
   953  			{ID: "seconds_behind_master", Name: "seconds"},
   954  		},
   955  	}
   956  	chartSlaveSQLIOThreadRunningState = module.Chart{
   957  		ID:       "slave_thread_running",
   958  		Title:    "I/O / SQL Thread Running State",
   959  		Units:    "boolean",
   960  		Fam:      "slave",
   961  		Ctx:      "mysql.slave_status",
   962  		Priority: prioSlaveSQLIOThreadRunningState,
   963  		Dims: module.Dims{
   964  			{ID: "slave_sql_running", Name: "sql_running"},
   965  			{ID: "slave_io_running", Name: "io_running"},
   966  		},
   967  	}
   968  )
   969  
   970  func newSlaveReplConnCharts(conn string) *module.Charts {
   971  	orig := conn
   972  	conn = strings.ToLower(conn)
   973  	cs := chartsSlaveReplication.Copy()
   974  	for _, chart := range *cs {
   975  		chart.ID += "_" + conn
   976  		chart.Title += " Connection " + orig
   977  		for _, dim := range chart.Dims {
   978  			dim.ID += "_" + conn
   979  		}
   980  	}
   981  	return cs
   982  }
   983  
   984  func newMariaDBUserStatisticsCharts(user string) *module.Charts {
   985  	lcUser := strings.ToLower(user)
   986  	charts := chartsTmplUserStats.Copy()
   987  	for _, c := range *charts {
   988  		c.ID = fmt.Sprintf(c.ID, lcUser)
   989  		c.Labels = []module.Label{
   990  			{Key: "user", Value: user},
   991  		}
   992  		for _, d := range c.Dims {
   993  			d.ID = fmt.Sprintf(d.ID, lcUser)
   994  		}
   995  	}
   996  	return charts
   997  }
   998  
   999  func newPerconaUserStatisticsCharts(user string) *module.Charts {
  1000  	lcUser := strings.ToLower(user)
  1001  	charts := chartsTmplPerconaUserStats.Copy()
  1002  	for _, c := range *charts {
  1003  		c.ID = fmt.Sprintf(c.ID, lcUser)
  1004  		c.Labels = []module.Label{
  1005  			{Key: "user", Value: user},
  1006  		}
  1007  		for _, d := range c.Dims {
  1008  			d.ID = fmt.Sprintf(d.ID, lcUser)
  1009  		}
  1010  	}
  1011  	return charts
  1012  }
  1013  
  1014  var (
  1015  	chartsTmplUserStats = module.Charts{
  1016  		chartUserStatsCPU.Copy(),
  1017  		chartTmplUserStatsRowsOperations.Copy(),
  1018  		chartTmplUserStatsCommands.Copy(),
  1019  		chartTmplUserStatsDeniedCommands.Copy(),
  1020  		chartTmplUserStatsTransactions.Copy(),
  1021  		chartTmplUserStatsBinlogWritten.Copy(),
  1022  		chartTmplUserStatsEmptyQueries.Copy(),
  1023  		chartTmplUserStatsCreatedConnections.Copy(),
  1024  		chartTmplUserStatsLostConnections.Copy(),
  1025  		chartTmplUserStatsDeniedConnections.Copy(),
  1026  	}
  1027  	chartsTmplPerconaUserStats = module.Charts{
  1028  		chartUserStatsCPU.Copy(),
  1029  		chartTmplPerconaUserStatsRowsOperations.Copy(),
  1030  		chartTmplUserStatsCommands.Copy(),
  1031  		chartTmplUserStatsDeniedCommands.Copy(),
  1032  		chartTmplUserStatsTransactions.Copy(),
  1033  		chartTmplUserStatsBinlogWritten.Copy(),
  1034  		chartTmplUserStatsEmptyQueries.Copy(),
  1035  		chartTmplUserStatsCreatedConnections.Copy(),
  1036  		chartTmplUserStatsLostConnections.Copy(),
  1037  		chartTmplUserStatsDeniedConnections.Copy(),
  1038  	}
  1039  
  1040  	chartUserStatsCPU = module.Chart{
  1041  		ID:       "userstats_cpu_%s",
  1042  		Title:    "User CPU Time",
  1043  		Units:    "percentage",
  1044  		Fam:      "user cpu time",
  1045  		Ctx:      "mysql.userstats_cpu",
  1046  		Priority: prioUserStatsCPUTime,
  1047  		Dims: module.Dims{
  1048  			{ID: "userstats_%s_cpu_time", Name: "used", Mul: 100, Div: 1000, Algo: module.Incremental},
  1049  		},
  1050  	}
  1051  	chartTmplUserStatsRowsOperations = module.Chart{
  1052  		ID:       "userstats_rows_%s",
  1053  		Title:    "User Rows Operations",
  1054  		Units:    "operations/s",
  1055  		Fam:      "user operations",
  1056  		Ctx:      "mysql.userstats_rows",
  1057  		Type:     module.Stacked,
  1058  		Priority: prioUserStatsRows,
  1059  		Dims: module.Dims{
  1060  			{ID: "userstats_%s_rows_read", Name: "read", Algo: module.Incremental},
  1061  			{ID: "userstats_%s_rows_sent", Name: "sent", Algo: module.Incremental},
  1062  			{ID: "userstats_%s_rows_updated", Name: "updated", Algo: module.Incremental},
  1063  			{ID: "userstats_%s_rows_inserted", Name: "inserted", Algo: module.Incremental},
  1064  			{ID: "userstats_%s_rows_deleted", Name: "deleted", Algo: module.Incremental},
  1065  		},
  1066  	}
  1067  	chartTmplPerconaUserStatsRowsOperations = module.Chart{
  1068  		ID:       "userstats_rows_%s",
  1069  		Title:    "User Rows Operations",
  1070  		Units:    "operations/s",
  1071  		Fam:      "user operations",
  1072  		Ctx:      "mysql.userstats_rows",
  1073  		Type:     module.Stacked,
  1074  		Priority: prioUserStatsRows,
  1075  		Dims: module.Dims{
  1076  			{ID: "userstats_%s_rows_fetched", Name: "fetched", Algo: module.Incremental},
  1077  			{ID: "userstats_%s_rows_updated", Name: "updated", Algo: module.Incremental},
  1078  		},
  1079  	}
  1080  	chartTmplUserStatsCommands = module.Chart{
  1081  		ID:       "userstats_commands_%s",
  1082  		Title:    "User Commands",
  1083  		Units:    "commands/s",
  1084  		Fam:      "user commands",
  1085  		Ctx:      "mysql.userstats_commands",
  1086  		Type:     module.Stacked,
  1087  		Priority: prioUserStatsCommands,
  1088  		Dims: module.Dims{
  1089  			{ID: "userstats_%s_select_commands", Name: "select", Algo: module.Incremental},
  1090  			{ID: "userstats_%s_update_commands", Name: "update", Algo: module.Incremental},
  1091  			{ID: "userstats_%s_other_commands", Name: "other", Algo: module.Incremental},
  1092  		},
  1093  	}
  1094  	chartTmplUserStatsDeniedCommands = module.Chart{
  1095  		ID:       "userstats_denied_commands_%s",
  1096  		Title:    "User Denied Commands",
  1097  		Units:    "commands/s",
  1098  		Fam:      "user commands denied",
  1099  		Ctx:      "mysql.userstats_denied_commands",
  1100  		Priority: prioUserStatsDeniedCommands,
  1101  		Dims: module.Dims{
  1102  			{ID: "userstats_%s_access_denied", Name: "denied", Algo: module.Incremental},
  1103  		},
  1104  	}
  1105  	chartTmplUserStatsTransactions = module.Chart{
  1106  		ID:       "userstats_transactions_%s",
  1107  		Title:    "User Transactions",
  1108  		Units:    "transactions/s",
  1109  		Fam:      "user transactions",
  1110  		Ctx:      "mysql.userstats_created_transactions",
  1111  		Type:     module.Area,
  1112  		Priority: prioUserStatsTransactions,
  1113  		Dims: module.Dims{
  1114  			{ID: "userstats_%s_commit_transactions", Name: "commit", Algo: module.Incremental},
  1115  			{ID: "userstats_%s_rollback_transactions", Name: "rollback", Algo: module.Incremental},
  1116  		},
  1117  	}
  1118  	chartTmplUserStatsBinlogWritten = module.Chart{
  1119  		ID:       "userstats_binlog_written_%s",
  1120  		Title:    "User Binlog Written",
  1121  		Units:    "B/s",
  1122  		Fam:      "user binlog written",
  1123  		Ctx:      "mysql.userstats_binlog_written",
  1124  		Priority: prioUserStatsBinlogWritten,
  1125  		Dims: module.Dims{
  1126  			{ID: "userstats_%s_binlog_bytes_written", Name: "written", Algo: module.Incremental},
  1127  		},
  1128  	}
  1129  	chartTmplUserStatsEmptyQueries = module.Chart{
  1130  		ID:       "userstats_empty_queries_%s",
  1131  		Title:    "User Empty Queries",
  1132  		Units:    "queries/s",
  1133  		Fam:      "user empty queries",
  1134  		Ctx:      "mysql.userstats_empty_queries",
  1135  		Priority: prioUserStatsEmptyQueries,
  1136  		Dims: module.Dims{
  1137  			{ID: "userstats_%s_empty_queries", Name: "empty", Algo: module.Incremental},
  1138  		},
  1139  	}
  1140  	chartTmplUserStatsCreatedConnections = module.Chart{
  1141  		ID:       "userstats_connections_%s",
  1142  		Title:    "User Created Connections",
  1143  		Units:    "connections/s",
  1144  		Fam:      "user connections created ",
  1145  		Ctx:      "mysql.userstats_connections",
  1146  		Priority: prioUserStatsConnections,
  1147  		Dims: module.Dims{
  1148  			{ID: "userstats_%s_total_connections", Name: "created", Algo: module.Incremental},
  1149  		},
  1150  	}
  1151  	chartTmplUserStatsLostConnections = module.Chart{
  1152  		ID:       "userstats_lost_connections_%s",
  1153  		Title:    "User Lost Connections",
  1154  		Units:    "connections/s",
  1155  		Fam:      "user connections lost",
  1156  		Ctx:      "mysql.userstats_lost_connections",
  1157  		Priority: prioUserStatsLostConnections,
  1158  		Dims: module.Dims{
  1159  			{ID: "userstats_%s_lost_connections", Name: "lost", Algo: module.Incremental},
  1160  		},
  1161  	}
  1162  	chartTmplUserStatsDeniedConnections = module.Chart{
  1163  		ID:       "userstats_denied_connections_%s",
  1164  		Title:    "User Denied Connections",
  1165  		Units:    "connections/s",
  1166  		Fam:      "user connections denied",
  1167  		Ctx:      "mysql.userstats_denied_connections",
  1168  		Priority: prioUserStatsDeniedConnections,
  1169  		Dims: module.Dims{
  1170  			{ID: "userstats_%s_denied_connections", Name: "denied", Algo: module.Incremental},
  1171  		},
  1172  	}
  1173  )
  1174  
  1175  func (m *MySQL) addSlaveReplicationConnCharts(conn string) {
  1176  	var charts *module.Charts
  1177  	if conn == "" {
  1178  		charts = chartsSlaveReplication.Copy()
  1179  	} else {
  1180  		charts = newSlaveReplConnCharts(conn)
  1181  	}
  1182  	if err := m.Charts().Add(*charts...); err != nil {
  1183  		m.Warning(err)
  1184  	}
  1185  }
  1186  
  1187  func (m *MySQL) addUserStatisticsCharts(user string) {
  1188  	if m.isPercona {
  1189  		if err := m.Charts().Add(*newPerconaUserStatisticsCharts(user)...); err != nil {
  1190  			m.Warning(err)
  1191  		}
  1192  	} else {
  1193  		if err := m.Charts().Add(*newMariaDBUserStatisticsCharts(user)...); err != nil {
  1194  			m.Warning(err)
  1195  		}
  1196  	}
  1197  }
  1198  
  1199  func (m *MySQL) addInnoDBOSLogCharts() {
  1200  	if err := m.Charts().Add(*chartsInnoDBOSLog.Copy()...); err != nil {
  1201  		m.Warning(err)
  1202  	}
  1203  }
  1204  
  1205  func (m *MySQL) addMyISAMCharts() {
  1206  	if err := m.Charts().Add(*chartsMyISAM.Copy()...); err != nil {
  1207  		m.Warning(err)
  1208  	}
  1209  }
  1210  
  1211  func (m *MySQL) addBinlogCharts() {
  1212  	if err := m.Charts().Add(*chartsBinlog.Copy()...); err != nil {
  1213  		m.Warning(err)
  1214  	}
  1215  }
  1216  
  1217  func (m *MySQL) addInnodbDeadlocksChart() {
  1218  	if err := m.Charts().Add(chartInnoDBDeadlocks.Copy()); err != nil {
  1219  		m.Warning(err)
  1220  	}
  1221  }
  1222  
  1223  func (m *MySQL) addQCacheCharts() {
  1224  	if err := m.Charts().Add(*chartsQCache.Copy()...); err != nil {
  1225  		m.Warning(err)
  1226  	}
  1227  }
  1228  
  1229  func (m *MySQL) addGaleraCharts() {
  1230  	if err := m.Charts().Add(*chartsGalera.Copy()...); err != nil {
  1231  		m.Warning(err)
  1232  	}
  1233  }
  1234  
  1235  func (m *MySQL) addTableOpenCacheOverflowChart() {
  1236  	if err := m.Charts().Add(chartTableOpenCacheOverflows.Copy()); err != nil {
  1237  		m.Warning(err)
  1238  	}
  1239  }