master
go 2,052 lines 107 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package mysql
4
5 import (
6 "bufio"
7 "bytes"
8 "context"
9 "database/sql/driver"
10 "errors"
11 "fmt"
12 "os"
13 "strings"
14 "testing"
15
16 "github.com/netdata/netdata/go/plugins/pkg/metrix"
17 "github.com/netdata/netdata/go/plugins/plugin/framework/chartengine"
18 "github.com/netdata/netdata/go/plugins/plugin/framework/charttpl"
19 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
20
21 "github.com/DATA-DOG/go-sqlmock"
22 "github.com/stretchr/testify/assert"
23 "github.com/stretchr/testify/require"
24 )
25
26 var (
27 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
28 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
29
30 dataSessionVariables, _ = os.ReadFile("testdata/session_variables.txt")
31
32 dataMySQLVer8030Version, _ = os.ReadFile("testdata/mysql/v8.0.30/version.txt")
33 dataMySQLVer8030GlobalStatus, _ = os.ReadFile("testdata/mysql/v8.0.30/global_status.txt")
34 dataMySQLVer8030GlobalVariables, _ = os.ReadFile("testdata/mysql/v8.0.30/global_variables.txt")
35 dataMySQLVer8030ReplicaStatusMultiSource, _ = os.ReadFile("testdata/mysql/v8.0.30/replica_status_multi_source.txt")
36 dataMySQLVer8030ProcessList, _ = os.ReadFile("testdata/mysql/v8.0.30/process_list.txt")
37 dataMySQLVer8030EngineInnoDBStatus, _ = os.ReadFile("testdata/mysql/v8.0.30/engine_innodb_status.txt")
38
39 dataPerconaVer8029Version, _ = os.ReadFile("testdata/percona/v8.0.29/version.txt")
40 dataPerconaVer8029GlobalStatus, _ = os.ReadFile("testdata/percona/v8.0.29/global_status.txt")
41 dataPerconaVer8029GlobalVariables, _ = os.ReadFile("testdata/percona/v8.0.29/global_variables.txt")
42 dataPerconaVer8029UserStatistics, _ = os.ReadFile("testdata/percona/v8.0.29/user_statistics.txt")
43 dataPerconaVer8029ProcessList, _ = os.ReadFile("testdata/percona/v8.0.29/process_list.txt")
44 dataPerconaVer8029EngineInnoDBStatus, _ = os.ReadFile("testdata/percona/v8.0.29/engine_innodb_status.txt")
45
46 dataMariaVer5564Version, _ = os.ReadFile("testdata/mariadb/v5.5.64/version.txt")
47 dataMariaVer5564GlobalStatus, _ = os.ReadFile("testdata/mariadb/v5.5.64/global_status.txt")
48 dataMariaVer5564GlobalVariables, _ = os.ReadFile("testdata/mariadb/v5.5.64/global_variables.txt")
49 dataMariaVer5564ProcessList, _ = os.ReadFile("testdata/mariadb/v5.5.64/process_list.txt")
50 dataMariaVer5564EngineInnoDBStatus, _ = os.ReadFile("testdata/mariadb/v5.5.64/engine_innodb_status.txt")
51
52 dataMariaVer1084Version, _ = os.ReadFile("testdata/mariadb/v10.8.4/version.txt")
53 dataMariaVer1084GlobalStatus, _ = os.ReadFile("testdata/mariadb/v10.8.4/global_status.txt")
54 dataMariaVer1084GlobalVariables, _ = os.ReadFile("testdata/mariadb/v10.8.4/global_variables.txt")
55 dataMariaVer1084AllSlavesStatusSingleSource, _ = os.ReadFile("testdata/mariadb/v10.8.4/all_slaves_status_single_source.txt")
56 dataMariaVer1084AllSlavesStatusMultiSource, _ = os.ReadFile("testdata/mariadb/v10.8.4/all_slaves_status_multi_source.txt")
57 dataMariaVer1084UserStatistics, _ = os.ReadFile("testdata/mariadb/v10.8.4/user_statistics.txt")
58 dataMariaVer1084ProcessList, _ = os.ReadFile("testdata/mariadb/v10.8.4/process_list.txt")
59 dataMariaVer1084EngineInnoDBStatus, _ = os.ReadFile("testdata/mariadb/v10.8.4/engine_innodb_status.txt")
60
61 dataMariaGaleraClusterVer1084Version, _ = os.ReadFile("testdata/mariadb/v10.8.4-galera-cluster/version.txt")
62 dataMariaGaleraClusterVer1084GlobalStatus, _ = os.ReadFile("testdata/mariadb/v10.8.4-galera-cluster/global_status.txt")
63 dataMariaGaleraClusterVer1084GlobalVariables, _ = os.ReadFile("testdata/mariadb/v10.8.4-galera-cluster/global_variables.txt")
64 dataMariaGaleraClusterVer1084UserStatistics, _ = os.ReadFile("testdata/mariadb/v10.8.4-galera-cluster/user_statistics.txt")
65 dataMariaGaleraClusterVer1084ProcessList, _ = os.ReadFile("testdata/mariadb/v10.8.4-galera-cluster/process_list.txt")
66 dataMariaGaleraClusterVer1084EngineInnoDBStatus, _ = os.ReadFile("testdata/mariadb/v10.8.4-galera-cluster/engine_innodb_status.txt")
67
68 dataMariaVer1145Version, _ = os.ReadFile("testdata/mariadb/v11.4.5/version.txt")
69 dataMariaVer1145UserStatistics, _ = os.ReadFile("testdata/mariadb/v11.4.5/user_statistics.txt")
70 )
71
72 func Test_testDataIsValid(t *testing.T) {
73 for name, data := range map[string][]byte{
74 "dataConfigJSON": dataConfigJSON,
75 "dataConfigYAML": dataConfigYAML,
76 "dataSessionVariables": dataSessionVariables,
77 "dataMySQLVer8030Version": dataMySQLVer8030Version,
78 "dataMySQLVer8030GlobalStatus": dataMySQLVer8030GlobalStatus,
79 "dataMySQLVer8030GlobalVariables": dataMySQLVer8030GlobalVariables,
80 "dataMySQLVer8030ReplicaStatusMultiSource": dataMySQLVer8030ReplicaStatusMultiSource,
81 "dataMySQLVer8030ProcessList": dataMySQLVer8030ProcessList,
82 "dataMySQLVer8030EngineInnoDBStatus": dataMySQLVer8030EngineInnoDBStatus,
83 "dataPerconaVer8029Version": dataPerconaVer8029Version,
84 "dataPerconaVer8029GlobalStatus": dataPerconaVer8029GlobalStatus,
85 "dataPerconaVer8029GlobalVariables": dataPerconaVer8029GlobalVariables,
86 "dataPerconaVer8029UserStatistics": dataPerconaVer8029UserStatistics,
87 "dataPerconaVer8029ProcessList": dataPerconaVer8029ProcessList,
88 "dataPerconaVer8029EngineInnoDBStatus": dataPerconaVer8029EngineInnoDBStatus,
89 "dataMariaVer5564Version": dataMariaVer5564Version,
90 "dataMariaVer5564GlobalStatus": dataMariaVer5564GlobalStatus,
91 "dataMariaVer5564GlobalVariables": dataMariaVer5564GlobalVariables,
92 "dataMariaVer5564ProcessList": dataMariaVer5564ProcessList,
93 "dataMariaVer5564EngineInnoDBStatus": dataMariaVer5564EngineInnoDBStatus,
94 "dataMariaVer1084Version": dataMariaVer1084Version,
95 "dataMariaVer1084GlobalStatus": dataMariaVer1084GlobalStatus,
96 "dataMariaVer1084GlobalVariables": dataMariaVer1084GlobalVariables,
97 "dataMariaVer1084AllSlavesStatusSingleSource": dataMariaVer1084AllSlavesStatusSingleSource,
98 "dataMariaVer1084AllSlavesStatusMultiSource": dataMariaVer1084AllSlavesStatusMultiSource,
99 "dataMariaVer1084UserStatistics": dataMariaVer1084UserStatistics,
100 "dataMariaVer1084ProcessList": dataMariaVer1084ProcessList,
101 "dataMariaVer1084EngineInnoDBStatus": dataMariaVer1084EngineInnoDBStatus,
102 "dataMariaGaleraClusterVer1084Version": dataMariaGaleraClusterVer1084Version,
103 "dataMariaGaleraClusterVer1084GlobalStatus": dataMariaGaleraClusterVer1084GlobalStatus,
104 "dataMariaGaleraClusterVer1084GlobalVariables": dataMariaGaleraClusterVer1084GlobalVariables,
105 "dataMariaGaleraClusterVer1084UserStatistics": dataMariaGaleraClusterVer1084UserStatistics,
106 "dataMariaGaleraClusterVer1084ProcessList": dataMariaGaleraClusterVer1084ProcessList,
107 "dataMariaGaleraClusterVer1084EngineInnoDBStatus": dataMariaGaleraClusterVer1084EngineInnoDBStatus,
108 "dataMariaVer1145Version": dataMariaVer1145Version,
109 "dataMariaVer1145UserStatistics": dataMariaVer1145UserStatistics,
110 } {
111 require.NotNil(t, data, fmt.Sprintf("read data: %s", name))
112 _, err := prepareMockRows(data)
113 require.NoError(t, err, fmt.Sprintf("prepare mock rows: %s", name))
114 }
115 }
116
117 func TestCollector_ConfigurationSerialize(t *testing.T) {
118 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
119 }
120
121 func TestCollector_Init(t *testing.T) {
122 tests := map[string]struct {
123 config Config
124 wantFail bool
125 }{
126 "empty DSN": {
127 config: Config{DSN: ""},
128 wantFail: true,
129 },
130 }
131
132 for name, test := range tests {
133 t.Run(name, func(t *testing.T) {
134 collr := New()
135 collr.Config = test.config
136
137 if test.wantFail {
138 assert.Error(t, collr.Init(context.Background()))
139 } else {
140 assert.NoError(t, collr.Init(context.Background()))
141 }
142 })
143 }
144 }
145
146 func TestCollector_Cleanup(t *testing.T) {
147 tests := map[string]func(t *testing.T) (collr *Collector, cleanup func()){
148 "db connection not initialized": func(t *testing.T) (collr *Collector, cleanup func()) {
149 return New(), func() {}
150 },
151 "db connection initialized": func(t *testing.T) (collr *Collector, cleanup func()) {
152 db, mock, err := sqlmock.New()
153 require.NoError(t, err)
154
155 mock.ExpectClose()
156 collr = New()
157 collr.db = db
158 cleanup = func() { _ = db.Close() }
159
160 return collr, cleanup
161 },
162 }
163
164 for name, prepare := range tests {
165 t.Run(name, func(t *testing.T) {
166 collr, cleanup := prepare(t)
167 defer cleanup()
168
169 assert.NotPanics(t, func() { collr.Cleanup(context.Background()) })
170 assert.Nil(t, collr.db)
171 })
172 }
173 }
174
175 func TestCollector_ChartTemplateYAML(t *testing.T) {
176 collr := New()
177 collecttest.AssertChartTemplateSchema(t, collr.ChartTemplateYAML())
178
179 spec, err := charttpl.DecodeYAML([]byte(collr.ChartTemplateYAML()))
180 require.NoError(t, err)
181
182 _, err = chartengine.Compile(spec, 1)
183 require.NoError(t, err)
184 }
185
186 func TestCollector_Check(t *testing.T) {
187 tests := map[string]struct {
188 prepareMock func(t *testing.T, m sqlmock.Sqlmock)
189 wantFail bool
190 }{
191 "success on mandatory queries": {
192 wantFail: false,
193 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
194 mockExpect(t, m, queryShowVersion, dataMariaVer1084Version)
195 mockExpect(t, m, queryShowGlobalStatusProbe, dataMariaVer1084GlobalStatus)
196 mockExpect(t, m, queryShowGlobalVariables, dataMariaVer1084GlobalVariables)
197 },
198 },
199 "fails when error on querying version": {
200 wantFail: true,
201 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
202 mockExpectErr(m, queryShowVersion)
203 },
204 },
205 "fails when error on querying global status": {
206 wantFail: true,
207 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
208 mockExpect(t, m, queryShowVersion, dataMariaVer1084Version)
209 mockExpectErr(m, queryShowGlobalStatusProbe)
210 },
211 },
212 "fails when error on querying global variables": {
213 wantFail: true,
214 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
215 mockExpect(t, m, queryShowVersion, dataMariaVer1084Version)
216 mockExpect(t, m, queryShowGlobalStatusProbe, dataMariaVer1084GlobalStatus)
217 mockExpectErr(m, queryShowGlobalVariables)
218 },
219 },
220 }
221
222 for name, test := range tests {
223 t.Run(name, func(t *testing.T) {
224 db, mock, err := sqlmock.New(
225 sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual),
226 )
227 require.NoError(t, err)
228 collr := New()
229 collr.db = db
230 defer func() { _ = db.Close() }()
231
232 require.NoError(t, collr.Init(context.Background()))
233
234 test.prepareMock(t, mock)
235
236 if test.wantFail {
237 assert.Error(t, collr.Check(context.Background()))
238 } else {
239 assert.NoError(t, collr.Check(context.Background()))
240 }
241 assert.NoError(t, mock.ExpectationsWereMet())
242 })
243 }
244 }
245
246 func TestCollector_Collect(t *testing.T) {
247 type testCaseStep struct {
248 prepareMock func(t *testing.T, m sqlmock.Sqlmock)
249 check func(t *testing.T, my *Collector)
250 }
251 tests := map[string][]testCaseStep{
252 "MariaDB-Standalone[v11.4.5]: success on all queries": {
253 {
254 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
255 mockExpect(t, m, queryShowVersion, dataMariaVer1145Version)
256 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
257 mockExpect(t, m, queryDisableSessionQueryLog, nil)
258 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
259 mockExpect(t, m, queryShowGlobalStatus, dataMariaVer1084GlobalStatus)
260 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMariaVer1084EngineInnoDBStatus)
261 mockExpect(t, m, queryShowGlobalVariables, dataMariaVer1084GlobalVariables)
262 mockExpect(t, m, queryShowAllSlavesStatus, nil)
263 mockExpect(t, m, queryShowUserStatistics, dataMariaVer1145UserStatistics)
264 mockExpect(t, m, queryShowProcessList, dataMariaVer1084ProcessList)
265 },
266 check: func(t *testing.T, collr *Collector) {
267 mx, err := collecttest.CollectScalarSeries(collr)
268 require.NoError(t, err)
269
270 expected := map[string]metrix.SampleValue{
271 "aborted_connects": 2,
272 "binlog_cache_disk_use": 0,
273 "binlog_cache_use": 0,
274 "binlog_stmt_cache_disk_use": 0,
275 "binlog_stmt_cache_use": 0,
276 "bytes_received": 81392,
277 "bytes_sent": 56794,
278 "com_delete": 0,
279 "com_insert": 0,
280 "com_replace": 0,
281 "com_select": 6,
282 "com_update": 0,
283 "connection_errors_accept": 0,
284 "connection_errors_internal": 0,
285 "connection_errors_max_connections": 0,
286 "connection_errors_peer_address": 0,
287 "connection_errors_select": 0,
288 "connection_errors_tcpwrap": 0,
289 "connections": 12,
290 "created_tmp_disk_tables": 0,
291 "created_tmp_files": 5,
292 "created_tmp_tables": 2,
293 "handler_commit": 30,
294 "handler_delete": 0,
295 "handler_prepare": 0,
296 "handler_read_first": 7,
297 "handler_read_key": 7,
298 "handler_read_next": 3,
299 "handler_read_prev": 0,
300 "handler_read_rnd": 0,
301 "handler_read_rnd_next": 626,
302 "handler_rollback": 0,
303 "handler_savepoint": 0,
304 "handler_savepoint_rollback": 0,
305 "handler_update": 3,
306 "handler_write": 13,
307 "innodb_buffer_pool_bytes_data": 5062656,
308 "innodb_buffer_pool_bytes_dirty": 475136,
309 "innodb_buffer_pool_pages_data": 309,
310 "innodb_buffer_pool_pages_dirty": 29,
311 "innodb_buffer_pool_pages_flushed": 0,
312 "innodb_buffer_pool_pages_free": 7755,
313 "innodb_buffer_pool_pages_misc": 0,
314 "innodb_buffer_pool_pages_total": 8064,
315 "innodb_buffer_pool_read_ahead": 0,
316 "innodb_buffer_pool_read_ahead_evicted": 0,
317 "innodb_buffer_pool_read_ahead_rnd": 0,
318 "innodb_buffer_pool_read_requests": 1911,
319 "innodb_buffer_pool_reads": 171,
320 "innodb_buffer_pool_wait_free": 0,
321 "innodb_buffer_pool_write_requests": 148,
322 "innodb_checkpoint_age": 184,
323 "innodb_data_fsyncs": 17,
324 "innodb_data_pending_fsyncs": 0,
325 "innodb_data_pending_reads": 0,
326 "innodb_data_pending_writes": 0,
327 "innodb_data_read": 2801664,
328 "innodb_data_reads": 185,
329 "innodb_data_writes": 16,
330 "innodb_data_written": 0,
331 "innodb_deadlocks": 0,
332 "innodb_last_checkpoint_at": 46601,
333 "innodb_log_file_size": 100663296,
334 "innodb_log_files_in_group": 1,
335 "innodb_log_group_capacity": 100663296,
336 "innodb_log_occupancy": 0,
337 "innodb_log_sequence_number": 46785,
338 "innodb_log_waits": 0,
339 "innodb_log_write_requests": 109,
340 "innodb_log_writes": 15,
341 "innodb_os_log_written": 6097,
342 "innodb_row_lock_current_waits": 0,
343 "innodb_rows_deleted": 0,
344 "innodb_rows_inserted": 0,
345 "innodb_rows_read": 0,
346 "innodb_rows_updated": 0,
347 "key_blocks_not_flushed": 0,
348 "key_blocks_unused": 107163,
349 "key_blocks_used": 0,
350 "key_read_requests": 0,
351 "key_reads": 0,
352 "key_write_requests": 0,
353 "key_writes": 0,
354 "max_connections": 151,
355 "max_used_connections": 1,
356 "open_files": 29,
357 "open_tables": 10,
358 "opened_files": 100,
359 "opened_tables": 16,
360 "process_list_fetch_query_duration": 0,
361 "process_list_longest_query_duration": 9,
362 "process_list_queries_count_system": 0,
363 "process_list_queries_count_user": 2,
364 "qcache_free_blocks": 1,
365 "qcache_free_memory": 1031272,
366 "qcache_hits": 0,
367 "qcache_inserts": 0,
368 "qcache_lowmem_prunes": 0,
369 "qcache_not_cached": 0,
370 "qcache_queries_in_cache": 0,
371 "qcache_total_blocks": 1,
372 "queries": 33,
373 "questions": 24,
374 "select_full_join": 0,
375 "select_full_range_join": 0,
376 "select_range": 0,
377 "select_range_check": 0,
378 "select_scan": 2,
379 "slow_queries": 0,
380 "sort_merge_passes": 0,
381 "sort_range": 0,
382 "sort_scan": 0,
383 "table_locks_immediate": 60,
384 "table_locks_waited": 0,
385 "table_open_cache": 2000,
386 "table_open_cache_overflows": 0,
387 "thread_cache_misses": 1666,
388 "threads_cached": 0,
389 "threads_connected": 1,
390 "threads_created": 2,
391 "threads_running": 3,
392 "userstats_access_denied{user=\"netdata\"}": 33,
393 "userstats_binlog_bytes_written{user=\"netdata\"}": 0,
394 "userstats_commit_transactions{user=\"netdata\"}": 0,
395 "userstats_cpu_time{user=\"netdata\"}": 40377,
396 "userstats_denied_connections{user=\"netdata\"}": 49698,
397 "userstats_empty_queries{user=\"netdata\"}": 66,
398 "userstats_lost_connections{user=\"netdata\"}": 0,
399 "userstats_other_commands{user=\"netdata\"}": 0,
400 "userstats_rollback_transactions{user=\"netdata\"}": 0,
401 "userstats_rows_deleted{user=\"netdata\"}": 0,
402 "userstats_rows_inserted{user=\"netdata\"}": 0,
403 "userstats_rows_read{user=\"netdata\"}": 0,
404 "userstats_rows_sent{user=\"netdata\"}": 99,
405 "userstats_rows_updated{user=\"netdata\"}": 0,
406 "userstats_select_commands{user=\"netdata\"}": 33,
407 "userstats_total_connections{user=\"netdata\"}": 1,
408 "userstats_update_commands{user=\"netdata\"}": 0,
409 "userstats_access_denied{user=\"root\"}": 0,
410 "userstats_binlog_bytes_written{user=\"root\"}": 0,
411 "userstats_commit_transactions{user=\"root\"}": 0,
412 "userstats_cpu_time{user=\"root\"}": 20188,
413 "userstats_denied_connections{user=\"root\"}": 0,
414 "userstats_empty_queries{user=\"root\"}": 0,
415 "userstats_lost_connections{user=\"root\"}": 0,
416 "userstats_other_commands{user=\"root\"}": 0,
417 "userstats_rollback_transactions{user=\"root\"}": 0,
418 "userstats_rows_deleted{user=\"root\"}": 0,
419 "userstats_rows_inserted{user=\"root\"}": 0,
420 "userstats_rows_read{user=\"root\"}": 0,
421 "userstats_rows_sent{user=\"root\"}": 2,
422 "userstats_rows_updated{user=\"root\"}": 0,
423 "userstats_select_commands{user=\"root\"}": 0,
424 "userstats_total_connections{user=\"root\"}": 1,
425 "userstats_update_commands{user=\"root\"}": 0,
426 }
427
428 copyProcessListQueryDuration(mx, expected)
429 assertExpectedMetrics(t, mx, expected)
430 },
431 },
432 },
433 "MariaDB-Standalone[v5.5.64]: success on all queries": {
434 {
435 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
436 mockExpect(t, m, queryShowVersion, dataMariaVer5564Version)
437 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
438 mockExpect(t, m, queryDisableSessionQueryLog, nil)
439 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
440 mockExpect(t, m, queryShowGlobalStatus, dataMariaVer5564GlobalStatus)
441 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMariaVer5564EngineInnoDBStatus)
442 mockExpect(t, m, queryShowGlobalVariables, dataMariaVer5564GlobalVariables)
443 mockExpect(t, m, queryShowSlaveStatus, nil)
444 mockExpect(t, m, queryShowProcessList, dataMariaVer5564ProcessList)
445 },
446 check: func(t *testing.T, collr *Collector) {
447 mx, err := collecttest.CollectScalarSeries(collr)
448 require.NoError(t, err)
449
450 expected := map[string]metrix.SampleValue{
451 "aborted_connects": 0,
452 "binlog_cache_disk_use": 0,
453 "binlog_cache_use": 0,
454 "binlog_stmt_cache_disk_use": 0,
455 "binlog_stmt_cache_use": 0,
456 "bytes_received": 639,
457 "bytes_sent": 41620,
458 "com_delete": 0,
459 "com_insert": 0,
460 "com_replace": 0,
461 "com_select": 4,
462 "com_update": 0,
463 "connections": 4,
464 "created_tmp_disk_tables": 0,
465 "created_tmp_files": 6,
466 "created_tmp_tables": 5,
467 "handler_commit": 0,
468 "handler_delete": 0,
469 "handler_prepare": 0,
470 "handler_read_first": 0,
471 "handler_read_key": 0,
472 "handler_read_next": 0,
473 "handler_read_prev": 0,
474 "handler_read_rnd": 0,
475 "handler_read_rnd_next": 1264,
476 "handler_rollback": 0,
477 "handler_savepoint": 0,
478 "handler_savepoint_rollback": 0,
479 "handler_update": 0,
480 "handler_write": 0,
481 "innodb_buffer_pool_bytes_data": 2342912,
482 "innodb_buffer_pool_bytes_dirty": 0,
483 "innodb_buffer_pool_pages_data": 143,
484 "innodb_buffer_pool_pages_dirty": 0,
485 "innodb_buffer_pool_pages_flushed": 0,
486 "innodb_buffer_pool_pages_free": 16240,
487 "innodb_buffer_pool_pages_misc": 0,
488 "innodb_buffer_pool_pages_total": 16383,
489 "innodb_buffer_pool_read_ahead": 0,
490 "innodb_buffer_pool_read_ahead_evicted": 0,
491 "innodb_buffer_pool_read_ahead_rnd": 0,
492 "innodb_buffer_pool_read_requests": 459,
493 "innodb_buffer_pool_reads": 144,
494 "innodb_buffer_pool_wait_free": 0,
495 "innodb_buffer_pool_write_requests": 0,
496 "innodb_checkpoint_age": 0,
497 "innodb_data_fsyncs": 3,
498 "innodb_data_pending_fsyncs": 0,
499 "innodb_data_pending_reads": 0,
500 "innodb_data_pending_writes": 0,
501 "innodb_data_read": 4542976,
502 "innodb_data_reads": 155,
503 "innodb_data_writes": 3,
504 "innodb_data_written": 1536,
505 "innodb_deadlocks": 0,
506 "innodb_last_checkpoint_at": 1597945,
507 "innodb_log_file_size": 5242880,
508 "innodb_log_files_in_group": 2,
509 "innodb_log_group_capacity": 10485760,
510 "innodb_log_occupancy": 0,
511 "innodb_log_sequence_number": 1597945,
512 "innodb_log_waits": 0,
513 "innodb_log_write_requests": 0,
514 "innodb_log_writes": 1,
515 "innodb_os_log_fsyncs": 3,
516 "innodb_os_log_pending_fsyncs": 0,
517 "innodb_os_log_pending_writes": 0,
518 "innodb_os_log_written": 512,
519 "innodb_row_lock_current_waits": 0,
520 "innodb_rows_deleted": 0,
521 "innodb_rows_inserted": 0,
522 "innodb_rows_read": 0,
523 "innodb_rows_updated": 0,
524 "key_blocks_not_flushed": 0,
525 "key_blocks_unused": 107171,
526 "key_blocks_used": 0,
527 "key_read_requests": 0,
528 "key_reads": 0,
529 "key_write_requests": 0,
530 "key_writes": 0,
531 "max_connections": 100,
532 "max_used_connections": 1,
533 "open_files": 21,
534 "open_tables": 26,
535 "opened_files": 84,
536 "opened_tables": 0,
537 "process_list_fetch_query_duration": 0,
538 "process_list_longest_query_duration": 9,
539 "process_list_queries_count_system": 0,
540 "process_list_queries_count_user": 2,
541 "qcache_free_blocks": 1,
542 "qcache_free_memory": 67091120,
543 "qcache_hits": 0,
544 "qcache_inserts": 0,
545 "qcache_lowmem_prunes": 0,
546 "qcache_not_cached": 4,
547 "qcache_queries_in_cache": 0,
548 "qcache_total_blocks": 1,
549 "queries": 12,
550 "questions": 11,
551 "select_full_join": 0,
552 "select_full_range_join": 0,
553 "select_range": 0,
554 "select_range_check": 0,
555 "select_scan": 5,
556 "slow_queries": 0,
557 "sort_merge_passes": 0,
558 "sort_range": 0,
559 "sort_scan": 0,
560 "table_locks_immediate": 36,
561 "table_locks_waited": 0,
562 "table_open_cache": 400,
563 "thread_cache_misses": 2500,
564 "threads_cached": 0,
565 "threads_connected": 1,
566 "threads_created": 1,
567 "threads_running": 1,
568 }
569
570 copyProcessListQueryDuration(mx, expected)
571 assertExpectedMetrics(t, mx, expected)
572 collecttest.AssertChartCoverage(t, collr, collecttest.ChartCoverageExpectation{
573 ExcludeContextPatterns: []string{
574 "mysql.userstats_*",
575 "mysql.slave_*",
576 "mysql.galera_*",
577 },
578 })
579 },
580 },
581 },
582 "MariaDB-Standalone[v10.8.4]: success on all queries": {
583 {
584 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
585 mockExpect(t, m, queryShowVersion, dataMariaVer1084Version)
586 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
587 mockExpect(t, m, queryDisableSessionQueryLog, nil)
588 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
589 mockExpect(t, m, queryShowGlobalStatus, dataMariaVer1084GlobalStatus)
590 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMariaVer1084EngineInnoDBStatus)
591 mockExpect(t, m, queryShowGlobalVariables, dataMariaVer1084GlobalVariables)
592 mockExpect(t, m, queryShowAllSlavesStatus, nil)
593 mockExpect(t, m, queryShowUserStatistics, dataMariaVer1084UserStatistics)
594 mockExpect(t, m, queryShowProcessList, dataMariaVer1084ProcessList)
595 },
596 check: func(t *testing.T, collr *Collector) {
597 mx, err := collecttest.CollectScalarSeries(collr)
598 require.NoError(t, err)
599
600 expected := map[string]metrix.SampleValue{
601
602 "aborted_connects": 2,
603 "binlog_cache_disk_use": 0,
604 "binlog_cache_use": 0,
605 "binlog_stmt_cache_disk_use": 0,
606 "binlog_stmt_cache_use": 0,
607 "bytes_received": 81392,
608 "bytes_sent": 56794,
609 "com_delete": 0,
610 "com_insert": 0,
611 "com_replace": 0,
612 "com_select": 6,
613 "com_update": 0,
614 "connection_errors_accept": 0,
615 "connection_errors_internal": 0,
616 "connection_errors_max_connections": 0,
617 "connection_errors_peer_address": 0,
618 "connection_errors_select": 0,
619 "connection_errors_tcpwrap": 0,
620 "connections": 12,
621 "created_tmp_disk_tables": 0,
622 "created_tmp_files": 5,
623 "created_tmp_tables": 2,
624 "handler_commit": 30,
625 "handler_delete": 0,
626 "handler_prepare": 0,
627 "handler_read_first": 7,
628 "handler_read_key": 7,
629 "handler_read_next": 3,
630 "handler_read_prev": 0,
631 "handler_read_rnd": 0,
632 "handler_read_rnd_next": 626,
633 "handler_rollback": 0,
634 "handler_savepoint": 0,
635 "handler_savepoint_rollback": 0,
636 "handler_update": 3,
637 "handler_write": 13,
638 "innodb_buffer_pool_bytes_data": 5062656,
639 "innodb_buffer_pool_bytes_dirty": 475136,
640 "innodb_buffer_pool_pages_data": 309,
641 "innodb_buffer_pool_pages_dirty": 29,
642 "innodb_buffer_pool_pages_flushed": 0,
643 "innodb_buffer_pool_pages_free": 7755,
644 "innodb_buffer_pool_pages_misc": 0,
645 "innodb_buffer_pool_pages_total": 8064,
646 "innodb_buffer_pool_read_ahead": 0,
647 "innodb_buffer_pool_read_ahead_evicted": 0,
648 "innodb_buffer_pool_read_ahead_rnd": 0,
649 "innodb_buffer_pool_read_requests": 1911,
650 "innodb_buffer_pool_reads": 171,
651 "innodb_buffer_pool_wait_free": 0,
652 "innodb_buffer_pool_write_requests": 148,
653 "innodb_checkpoint_age": 184,
654 "innodb_data_fsyncs": 17,
655 "innodb_data_pending_fsyncs": 0,
656 "innodb_data_pending_reads": 0,
657 "innodb_data_pending_writes": 0,
658 "innodb_data_read": 2801664,
659 "innodb_data_reads": 185,
660 "innodb_data_writes": 16,
661 "innodb_data_written": 0,
662 "innodb_deadlocks": 0,
663 "innodb_last_checkpoint_at": 46601,
664 "innodb_log_file_size": 100663296,
665 "innodb_log_files_in_group": 1,
666 "innodb_log_group_capacity": 100663296,
667 "innodb_log_occupancy": 0,
668 "innodb_log_sequence_number": 46785,
669 "innodb_log_waits": 0,
670 "innodb_log_write_requests": 109,
671 "innodb_log_writes": 15,
672 "innodb_os_log_written": 6097,
673 "innodb_row_lock_current_waits": 0,
674 "innodb_rows_deleted": 0,
675 "innodb_rows_inserted": 0,
676 "innodb_rows_read": 0,
677 "innodb_rows_updated": 0,
678 "key_blocks_not_flushed": 0,
679 "key_blocks_unused": 107163,
680 "key_blocks_used": 0,
681 "key_read_requests": 0,
682 "key_reads": 0,
683 "key_write_requests": 0,
684 "key_writes": 0,
685 "max_connections": 151,
686 "max_used_connections": 1,
687 "open_files": 29,
688 "open_tables": 10,
689 "opened_files": 100,
690 "opened_tables": 16,
691 "process_list_fetch_query_duration": 0,
692 "process_list_longest_query_duration": 9,
693 "process_list_queries_count_system": 0,
694 "process_list_queries_count_user": 2,
695 "qcache_free_blocks": 1,
696 "qcache_free_memory": 1031272,
697 "qcache_hits": 0,
698 "qcache_inserts": 0,
699 "qcache_lowmem_prunes": 0,
700 "qcache_not_cached": 0,
701 "qcache_queries_in_cache": 0,
702 "qcache_total_blocks": 1,
703 "queries": 33,
704 "questions": 24,
705 "select_full_join": 0,
706 "select_full_range_join": 0,
707 "select_range": 0,
708 "select_range_check": 0,
709 "select_scan": 2,
710 "slow_queries": 0,
711 "sort_merge_passes": 0,
712 "sort_range": 0,
713 "sort_scan": 0,
714 "table_locks_immediate": 60,
715 "table_locks_waited": 0,
716 "table_open_cache": 2000,
717 "table_open_cache_overflows": 0,
718 "thread_cache_misses": 1666,
719 "threads_cached": 0,
720 "threads_connected": 1,
721 "threads_created": 2,
722 "threads_running": 3,
723 "userstats_access_denied{user=\"netdata\"}": 33,
724 "userstats_binlog_bytes_written{user=\"netdata\"}": 0,
725 "userstats_commit_transactions{user=\"netdata\"}": 0,
726 "userstats_cpu_time{user=\"netdata\"}": 77,
727 "userstats_denied_connections{user=\"netdata\"}": 49698,
728 "userstats_empty_queries{user=\"netdata\"}": 66,
729 "userstats_lost_connections{user=\"netdata\"}": 0,
730 "userstats_other_commands{user=\"netdata\"}": 0,
731 "userstats_rollback_transactions{user=\"netdata\"}": 0,
732 "userstats_rows_deleted{user=\"netdata\"}": 0,
733 "userstats_rows_inserted{user=\"netdata\"}": 0,
734 "userstats_rows_read{user=\"netdata\"}": 0,
735 "userstats_rows_sent{user=\"netdata\"}": 99,
736 "userstats_rows_updated{user=\"netdata\"}": 0,
737 "userstats_select_commands{user=\"netdata\"}": 33,
738 "userstats_total_connections{user=\"netdata\"}": 1,
739 "userstats_update_commands{user=\"netdata\"}": 0,
740 "userstats_access_denied{user=\"root\"}": 0,
741 "userstats_binlog_bytes_written{user=\"root\"}": 0,
742 "userstats_commit_transactions{user=\"root\"}": 0,
743 "userstats_cpu_time{user=\"root\"}": 0,
744 "userstats_denied_connections{user=\"root\"}": 0,
745 "userstats_empty_queries{user=\"root\"}": 0,
746 "userstats_lost_connections{user=\"root\"}": 0,
747 "userstats_other_commands{user=\"root\"}": 0,
748 "userstats_rollback_transactions{user=\"root\"}": 0,
749 "userstats_rows_deleted{user=\"root\"}": 0,
750 "userstats_rows_inserted{user=\"root\"}": 0,
751 "userstats_rows_read{user=\"root\"}": 0,
752 "userstats_rows_sent{user=\"root\"}": 2,
753 "userstats_rows_updated{user=\"root\"}": 0,
754 "userstats_select_commands{user=\"root\"}": 0,
755 "userstats_total_connections{user=\"root\"}": 1,
756 "userstats_update_commands{user=\"root\"}": 0,
757 }
758
759 copyProcessListQueryDuration(mx, expected)
760 assertExpectedMetrics(t, mx, expected)
761 },
762 },
763 },
764 "MariaDB-SingleSourceReplication[v10.8.4]: success on all queries": {
765 {
766 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
767 mockExpect(t, m, queryShowVersion, dataMariaVer1084Version)
768 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
769 mockExpect(t, m, queryDisableSessionQueryLog, nil)
770 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
771 mockExpect(t, m, queryShowGlobalStatus, dataMariaVer1084GlobalStatus)
772 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMariaVer1084EngineInnoDBStatus)
773 mockExpect(t, m, queryShowGlobalVariables, dataMariaVer1084GlobalVariables)
774 mockExpect(t, m, queryShowAllSlavesStatus, dataMariaVer1084AllSlavesStatusSingleSource)
775 mockExpect(t, m, queryShowUserStatistics, dataMariaVer1084UserStatistics)
776 mockExpect(t, m, queryShowProcessList, dataMariaVer1084ProcessList)
777 },
778 check: func(t *testing.T, collr *Collector) {
779 mx, err := collecttest.CollectScalarSeries(collr)
780 require.NoError(t, err)
781
782 expected := map[string]metrix.SampleValue{
783 "aborted_connects": 2,
784 "binlog_cache_disk_use": 0,
785 "binlog_cache_use": 0,
786 "binlog_stmt_cache_disk_use": 0,
787 "binlog_stmt_cache_use": 0,
788 "bytes_received": 81392,
789 "bytes_sent": 56794,
790 "com_delete": 0,
791 "com_insert": 0,
792 "com_replace": 0,
793 "com_select": 6,
794 "com_update": 0,
795 "connection_errors_accept": 0,
796 "connection_errors_internal": 0,
797 "connection_errors_max_connections": 0,
798 "connection_errors_peer_address": 0,
799 "connection_errors_select": 0,
800 "connection_errors_tcpwrap": 0,
801 "connections": 12,
802 "created_tmp_disk_tables": 0,
803 "created_tmp_files": 5,
804 "created_tmp_tables": 2,
805 "handler_commit": 30,
806 "handler_delete": 0,
807 "handler_prepare": 0,
808 "handler_read_first": 7,
809 "handler_read_key": 7,
810 "handler_read_next": 3,
811 "handler_read_prev": 0,
812 "handler_read_rnd": 0,
813 "handler_read_rnd_next": 626,
814 "handler_rollback": 0,
815 "handler_savepoint": 0,
816 "handler_savepoint_rollback": 0,
817 "handler_update": 3,
818 "handler_write": 13,
819 "innodb_buffer_pool_bytes_data": 5062656,
820 "innodb_buffer_pool_bytes_dirty": 475136,
821 "innodb_buffer_pool_pages_data": 309,
822 "innodb_buffer_pool_pages_dirty": 29,
823 "innodb_buffer_pool_pages_flushed": 0,
824 "innodb_buffer_pool_pages_free": 7755,
825 "innodb_buffer_pool_pages_misc": 0,
826 "innodb_buffer_pool_pages_total": 8064,
827 "innodb_buffer_pool_read_ahead": 0,
828 "innodb_buffer_pool_read_ahead_evicted": 0,
829 "innodb_buffer_pool_read_ahead_rnd": 0,
830 "innodb_buffer_pool_read_requests": 1911,
831 "innodb_buffer_pool_reads": 171,
832 "innodb_buffer_pool_wait_free": 0,
833 "innodb_buffer_pool_write_requests": 148,
834 "innodb_checkpoint_age": 184,
835 "innodb_data_fsyncs": 17,
836 "innodb_data_pending_fsyncs": 0,
837 "innodb_data_pending_reads": 0,
838 "innodb_data_pending_writes": 0,
839 "innodb_data_read": 2801664,
840 "innodb_data_reads": 185,
841 "innodb_data_writes": 16,
842 "innodb_data_written": 0,
843 "innodb_deadlocks": 0,
844 "innodb_last_checkpoint_at": 46601,
845 "innodb_log_file_size": 100663296,
846 "innodb_log_files_in_group": 1,
847 "innodb_log_group_capacity": 100663296,
848 "innodb_log_occupancy": 0,
849 "innodb_log_sequence_number": 46785,
850 "innodb_log_waits": 0,
851 "innodb_log_write_requests": 109,
852 "innodb_log_writes": 15,
853 "innodb_os_log_written": 6097,
854 "innodb_row_lock_current_waits": 0,
855 "innodb_rows_deleted": 0,
856 "innodb_rows_inserted": 0,
857 "innodb_rows_read": 0,
858 "innodb_rows_updated": 0,
859 "key_blocks_not_flushed": 0,
860 "key_blocks_unused": 107163,
861 "key_blocks_used": 0,
862 "key_read_requests": 0,
863 "key_reads": 0,
864 "key_write_requests": 0,
865 "key_writes": 0,
866 "max_connections": 151,
867 "max_used_connections": 1,
868 "open_files": 29,
869 "open_tables": 10,
870 "opened_files": 100,
871 "opened_tables": 16,
872 "process_list_fetch_query_duration": 0,
873 "process_list_longest_query_duration": 9,
874 "process_list_queries_count_system": 0,
875 "process_list_queries_count_user": 2,
876 "qcache_free_blocks": 1,
877 "qcache_free_memory": 1031272,
878 "qcache_hits": 0,
879 "qcache_inserts": 0,
880 "qcache_lowmem_prunes": 0,
881 "qcache_not_cached": 0,
882 "qcache_queries_in_cache": 0,
883 "qcache_total_blocks": 1,
884 "queries": 33,
885 "questions": 24,
886 "seconds_behind_master{connection=\"\"}": 0,
887 "select_full_join": 0,
888 "select_full_range_join": 0,
889 "select_range": 0,
890 "select_range_check": 0,
891 "select_scan": 2,
892 "slave_io_running{connection=\"\"}": 1,
893 "slave_sql_running{connection=\"\"}": 1,
894 "slow_queries": 0,
895 "sort_merge_passes": 0,
896 "sort_range": 0,
897 "sort_scan": 0,
898 "table_locks_immediate": 60,
899 "table_locks_waited": 0,
900 "table_open_cache": 2000,
901 "table_open_cache_overflows": 0,
902 "thread_cache_misses": 1666,
903 "threads_cached": 0,
904 "threads_connected": 1,
905 "threads_created": 2,
906 "threads_running": 3,
907 "userstats_access_denied{user=\"netdata\"}": 33,
908 "userstats_binlog_bytes_written{user=\"netdata\"}": 0,
909 "userstats_commit_transactions{user=\"netdata\"}": 0,
910 "userstats_cpu_time{user=\"netdata\"}": 77,
911 "userstats_denied_connections{user=\"netdata\"}": 49698,
912 "userstats_empty_queries{user=\"netdata\"}": 66,
913 "userstats_lost_connections{user=\"netdata\"}": 0,
914 "userstats_other_commands{user=\"netdata\"}": 0,
915 "userstats_rollback_transactions{user=\"netdata\"}": 0,
916 "userstats_rows_deleted{user=\"netdata\"}": 0,
917 "userstats_rows_inserted{user=\"netdata\"}": 0,
918 "userstats_rows_read{user=\"netdata\"}": 0,
919 "userstats_rows_sent{user=\"netdata\"}": 99,
920 "userstats_rows_updated{user=\"netdata\"}": 0,
921 "userstats_select_commands{user=\"netdata\"}": 33,
922 "userstats_total_connections{user=\"netdata\"}": 1,
923 "userstats_update_commands{user=\"netdata\"}": 0,
924 "userstats_access_denied{user=\"root\"}": 0,
925 "userstats_binlog_bytes_written{user=\"root\"}": 0,
926 "userstats_commit_transactions{user=\"root\"}": 0,
927 "userstats_cpu_time{user=\"root\"}": 0,
928 "userstats_denied_connections{user=\"root\"}": 0,
929 "userstats_empty_queries{user=\"root\"}": 0,
930 "userstats_lost_connections{user=\"root\"}": 0,
931 "userstats_other_commands{user=\"root\"}": 0,
932 "userstats_rollback_transactions{user=\"root\"}": 0,
933 "userstats_rows_deleted{user=\"root\"}": 0,
934 "userstats_rows_inserted{user=\"root\"}": 0,
935 "userstats_rows_read{user=\"root\"}": 0,
936 "userstats_rows_sent{user=\"root\"}": 2,
937 "userstats_rows_updated{user=\"root\"}": 0,
938 "userstats_select_commands{user=\"root\"}": 0,
939 "userstats_total_connections{user=\"root\"}": 1,
940 "userstats_update_commands{user=\"root\"}": 0,
941 }
942
943 copyProcessListQueryDuration(mx, expected)
944 assertExpectedMetrics(t, mx, expected)
945 collecttest.AssertChartCoverage(t, collr, collecttest.ChartCoverageExpectation{
946 ExcludeContextPatterns: []string{
947 "mysql.galera_*",
948 },
949 })
950 },
951 },
952 },
953 "MariaDB-MultiSourceReplication[v10.8.4]: success on all queries": {
954 {
955 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
956 mockExpect(t, m, queryShowVersion, dataMariaVer1084Version)
957 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
958 mockExpect(t, m, queryDisableSessionQueryLog, nil)
959 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
960 mockExpect(t, m, queryShowGlobalStatus, dataMariaVer1084GlobalStatus)
961 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMariaVer1084EngineInnoDBStatus)
962 mockExpect(t, m, queryShowGlobalVariables, dataMariaVer1084GlobalVariables)
963 mockExpect(t, m, queryShowAllSlavesStatus, dataMariaVer1084AllSlavesStatusMultiSource)
964 mockExpect(t, m, queryShowUserStatistics, dataMariaVer1084UserStatistics)
965 mockExpect(t, m, queryShowProcessList, dataMariaVer1084ProcessList)
966 },
967 check: func(t *testing.T, collr *Collector) {
968 mx, err := collecttest.CollectScalarSeries(collr)
969 require.NoError(t, err)
970
971 expected := map[string]metrix.SampleValue{
972 "aborted_connects": 2,
973 "binlog_cache_disk_use": 0,
974 "binlog_cache_use": 0,
975 "binlog_stmt_cache_disk_use": 0,
976 "binlog_stmt_cache_use": 0,
977 "bytes_received": 81392,
978 "bytes_sent": 56794,
979 "com_delete": 0,
980 "com_insert": 0,
981 "com_replace": 0,
982 "com_select": 6,
983 "com_update": 0,
984 "connection_errors_accept": 0,
985 "connection_errors_internal": 0,
986 "connection_errors_max_connections": 0,
987 "connection_errors_peer_address": 0,
988 "connection_errors_select": 0,
989 "connection_errors_tcpwrap": 0,
990 "connections": 12,
991 "created_tmp_disk_tables": 0,
992 "created_tmp_files": 5,
993 "created_tmp_tables": 2,
994 "handler_commit": 30,
995 "handler_delete": 0,
996 "handler_prepare": 0,
997 "handler_read_first": 7,
998 "handler_read_key": 7,
999 "handler_read_next": 3,
1000 "handler_read_prev": 0,
1001 "handler_read_rnd": 0,
1002 "handler_read_rnd_next": 626,
1003 "handler_rollback": 0,
1004 "handler_savepoint": 0,
1005 "handler_savepoint_rollback": 0,
1006 "handler_update": 3,
1007 "handler_write": 13,
1008 "innodb_buffer_pool_bytes_data": 5062656,
1009 "innodb_buffer_pool_bytes_dirty": 475136,
1010 "innodb_buffer_pool_pages_data": 309,
1011 "innodb_buffer_pool_pages_dirty": 29,
1012 "innodb_buffer_pool_pages_flushed": 0,
1013 "innodb_buffer_pool_pages_free": 7755,
1014 "innodb_buffer_pool_pages_misc": 0,
1015 "innodb_buffer_pool_pages_total": 8064,
1016 "innodb_buffer_pool_read_ahead": 0,
1017 "innodb_buffer_pool_read_ahead_evicted": 0,
1018 "innodb_buffer_pool_read_ahead_rnd": 0,
1019 "innodb_buffer_pool_read_requests": 1911,
1020 "innodb_buffer_pool_reads": 171,
1021 "innodb_buffer_pool_wait_free": 0,
1022 "innodb_buffer_pool_write_requests": 148,
1023 "innodb_checkpoint_age": 184,
1024 "innodb_data_fsyncs": 17,
1025 "innodb_data_pending_fsyncs": 0,
1026 "innodb_data_pending_reads": 0,
1027 "innodb_data_pending_writes": 0,
1028 "innodb_data_read": 2801664,
1029 "innodb_data_reads": 185,
1030 "innodb_data_writes": 16,
1031 "innodb_data_written": 0,
1032 "innodb_deadlocks": 0,
1033 "innodb_last_checkpoint_at": 46601,
1034 "innodb_log_file_size": 100663296,
1035 "innodb_log_files_in_group": 1,
1036 "innodb_log_group_capacity": 100663296,
1037 "innodb_log_occupancy": 0,
1038 "innodb_log_sequence_number": 46785,
1039 "innodb_log_waits": 0,
1040 "innodb_log_write_requests": 109,
1041 "innodb_log_writes": 15,
1042 "innodb_os_log_written": 6097,
1043 "innodb_row_lock_current_waits": 0,
1044 "innodb_rows_deleted": 0,
1045 "innodb_rows_inserted": 0,
1046 "innodb_rows_read": 0,
1047 "innodb_rows_updated": 0,
1048 "key_blocks_not_flushed": 0,
1049 "key_blocks_unused": 107163,
1050 "key_blocks_used": 0,
1051 "key_read_requests": 0,
1052 "key_reads": 0,
1053 "key_write_requests": 0,
1054 "key_writes": 0,
1055 "max_connections": 151,
1056 "max_used_connections": 1,
1057 "open_files": 29,
1058 "open_tables": 10,
1059 "opened_files": 100,
1060 "opened_tables": 16,
1061 "process_list_fetch_query_duration": 0,
1062 "process_list_longest_query_duration": 9,
1063 "process_list_queries_count_system": 0,
1064 "process_list_queries_count_user": 2,
1065 "qcache_free_blocks": 1,
1066 "qcache_free_memory": 1031272,
1067 "qcache_hits": 0,
1068 "qcache_inserts": 0,
1069 "qcache_lowmem_prunes": 0,
1070 "qcache_not_cached": 0,
1071 "qcache_queries_in_cache": 0,
1072 "qcache_total_blocks": 1,
1073 "queries": 33,
1074 "questions": 24,
1075 "seconds_behind_master{connection=\"master1\"}": 0,
1076 "seconds_behind_master{connection=\"master2\"}": 0,
1077 "select_full_join": 0,
1078 "select_full_range_join": 0,
1079 "select_range": 0,
1080 "select_range_check": 0,
1081 "select_scan": 2,
1082 "slave_io_running{connection=\"master1\"}": 1,
1083 "slave_io_running{connection=\"master2\"}": 1,
1084 "slave_sql_running{connection=\"master1\"}": 1,
1085 "slave_sql_running{connection=\"master2\"}": 1,
1086 "slow_queries": 0,
1087 "sort_merge_passes": 0,
1088 "sort_range": 0,
1089 "sort_scan": 0,
1090 "table_locks_immediate": 60,
1091 "table_locks_waited": 0,
1092 "table_open_cache": 2000,
1093 "table_open_cache_overflows": 0,
1094 "thread_cache_misses": 1666,
1095 "threads_cached": 0,
1096 "threads_connected": 1,
1097 "threads_created": 2,
1098 "threads_running": 3,
1099 "userstats_access_denied{user=\"netdata\"}": 33,
1100 "userstats_binlog_bytes_written{user=\"netdata\"}": 0,
1101 "userstats_commit_transactions{user=\"netdata\"}": 0,
1102 "userstats_cpu_time{user=\"netdata\"}": 77,
1103 "userstats_denied_connections{user=\"netdata\"}": 49698,
1104 "userstats_empty_queries{user=\"netdata\"}": 66,
1105 "userstats_lost_connections{user=\"netdata\"}": 0,
1106 "userstats_other_commands{user=\"netdata\"}": 0,
1107 "userstats_rollback_transactions{user=\"netdata\"}": 0,
1108 "userstats_rows_deleted{user=\"netdata\"}": 0,
1109 "userstats_rows_inserted{user=\"netdata\"}": 0,
1110 "userstats_rows_read{user=\"netdata\"}": 0,
1111 "userstats_rows_sent{user=\"netdata\"}": 99,
1112 "userstats_rows_updated{user=\"netdata\"}": 0,
1113 "userstats_select_commands{user=\"netdata\"}": 33,
1114 "userstats_total_connections{user=\"netdata\"}": 1,
1115 "userstats_update_commands{user=\"netdata\"}": 0,
1116 "userstats_access_denied{user=\"root\"}": 0,
1117 "userstats_binlog_bytes_written{user=\"root\"}": 0,
1118 "userstats_commit_transactions{user=\"root\"}": 0,
1119 "userstats_cpu_time{user=\"root\"}": 0,
1120 "userstats_denied_connections{user=\"root\"}": 0,
1121 "userstats_empty_queries{user=\"root\"}": 0,
1122 "userstats_lost_connections{user=\"root\"}": 0,
1123 "userstats_other_commands{user=\"root\"}": 0,
1124 "userstats_rollback_transactions{user=\"root\"}": 0,
1125 "userstats_rows_deleted{user=\"root\"}": 0,
1126 "userstats_rows_inserted{user=\"root\"}": 0,
1127 "userstats_rows_read{user=\"root\"}": 0,
1128 "userstats_rows_sent{user=\"root\"}": 2,
1129 "userstats_rows_updated{user=\"root\"}": 0,
1130 "userstats_select_commands{user=\"root\"}": 0,
1131 "userstats_total_connections{user=\"root\"}": 1,
1132 "userstats_update_commands{user=\"root\"}": 0,
1133 }
1134
1135 copyProcessListQueryDuration(mx, expected)
1136 assertExpectedMetrics(t, mx, expected)
1137 },
1138 },
1139 },
1140 "MariaDB-MultiSourceReplication[v10.8.4]: error on slaves status (no permissions)": {
1141 {
1142 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
1143 mockExpect(t, m, queryShowVersion, dataMariaVer1084Version)
1144 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
1145 mockExpect(t, m, queryDisableSessionQueryLog, nil)
1146 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
1147 mockExpect(t, m, queryShowGlobalStatus, dataMariaVer1084GlobalStatus)
1148 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMariaVer1084EngineInnoDBStatus)
1149 mockExpect(t, m, queryShowGlobalVariables, dataMariaVer1084GlobalVariables)
1150 mockExpectErr(m, queryShowAllSlavesStatus)
1151 mockExpect(t, m, queryShowUserStatistics, dataMariaVer1084UserStatistics)
1152 mockExpect(t, m, queryShowProcessList, dataMariaVer1084ProcessList)
1153 },
1154 check: func(t *testing.T, collr *Collector) {
1155 mx, err := collecttest.CollectScalarSeries(collr)
1156 require.NoError(t, err)
1157
1158 expected := map[string]metrix.SampleValue{
1159 "aborted_connects": 2,
1160 "binlog_cache_disk_use": 0,
1161 "binlog_cache_use": 0,
1162 "binlog_stmt_cache_disk_use": 0,
1163 "binlog_stmt_cache_use": 0,
1164 "bytes_received": 81392,
1165 "bytes_sent": 56794,
1166 "com_delete": 0,
1167 "com_insert": 0,
1168 "com_replace": 0,
1169 "com_select": 6,
1170 "com_update": 0,
1171 "connection_errors_accept": 0,
1172 "connection_errors_internal": 0,
1173 "connection_errors_max_connections": 0,
1174 "connection_errors_peer_address": 0,
1175 "connection_errors_select": 0,
1176 "connection_errors_tcpwrap": 0,
1177 "connections": 12,
1178 "created_tmp_disk_tables": 0,
1179 "created_tmp_files": 5,
1180 "created_tmp_tables": 2,
1181 "handler_commit": 30,
1182 "handler_delete": 0,
1183 "handler_prepare": 0,
1184 "handler_read_first": 7,
1185 "handler_read_key": 7,
1186 "handler_read_next": 3,
1187 "handler_read_prev": 0,
1188 "handler_read_rnd": 0,
1189 "handler_read_rnd_next": 626,
1190 "handler_rollback": 0,
1191 "handler_savepoint": 0,
1192 "handler_savepoint_rollback": 0,
1193 "handler_update": 3,
1194 "handler_write": 13,
1195 "innodb_buffer_pool_bytes_data": 5062656,
1196 "innodb_buffer_pool_bytes_dirty": 475136,
1197 "innodb_buffer_pool_pages_data": 309,
1198 "innodb_buffer_pool_pages_dirty": 29,
1199 "innodb_buffer_pool_pages_flushed": 0,
1200 "innodb_buffer_pool_pages_free": 7755,
1201 "innodb_buffer_pool_pages_misc": 0,
1202 "innodb_buffer_pool_pages_total": 8064,
1203 "innodb_buffer_pool_read_ahead": 0,
1204 "innodb_buffer_pool_read_ahead_evicted": 0,
1205 "innodb_buffer_pool_read_ahead_rnd": 0,
1206 "innodb_buffer_pool_read_requests": 1911,
1207 "innodb_buffer_pool_reads": 171,
1208 "innodb_buffer_pool_wait_free": 0,
1209 "innodb_buffer_pool_write_requests": 148,
1210 "innodb_checkpoint_age": 184,
1211 "innodb_data_fsyncs": 17,
1212 "innodb_data_pending_fsyncs": 0,
1213 "innodb_data_pending_reads": 0,
1214 "innodb_data_pending_writes": 0,
1215 "innodb_data_read": 2801664,
1216 "innodb_data_reads": 185,
1217 "innodb_data_writes": 16,
1218 "innodb_data_written": 0,
1219 "innodb_deadlocks": 0,
1220 "innodb_last_checkpoint_at": 46601,
1221 "innodb_log_file_size": 100663296,
1222 "innodb_log_files_in_group": 1,
1223 "innodb_log_group_capacity": 100663296,
1224 "innodb_log_occupancy": 0,
1225 "innodb_log_sequence_number": 46785,
1226 "innodb_log_waits": 0,
1227 "innodb_log_write_requests": 109,
1228 "innodb_log_writes": 15,
1229 "innodb_os_log_written": 6097,
1230 "innodb_row_lock_current_waits": 0,
1231 "innodb_rows_deleted": 0,
1232 "innodb_rows_inserted": 0,
1233 "innodb_rows_read": 0,
1234 "innodb_rows_updated": 0,
1235 "key_blocks_not_flushed": 0,
1236 "key_blocks_unused": 107163,
1237 "key_blocks_used": 0,
1238 "key_read_requests": 0,
1239 "key_reads": 0,
1240 "key_write_requests": 0,
1241 "key_writes": 0,
1242 "max_connections": 151,
1243 "max_used_connections": 1,
1244 "open_files": 29,
1245 "open_tables": 10,
1246 "opened_files": 100,
1247 "opened_tables": 16,
1248 "process_list_fetch_query_duration": 0,
1249 "process_list_longest_query_duration": 9,
1250 "process_list_queries_count_system": 0,
1251 "process_list_queries_count_user": 2,
1252 "qcache_free_blocks": 1,
1253 "qcache_free_memory": 1031272,
1254 "qcache_hits": 0,
1255 "qcache_inserts": 0,
1256 "qcache_lowmem_prunes": 0,
1257 "qcache_not_cached": 0,
1258 "qcache_queries_in_cache": 0,
1259 "qcache_total_blocks": 1,
1260 "queries": 33,
1261 "questions": 24,
1262 "select_full_join": 0,
1263 "select_full_range_join": 0,
1264 "select_range": 0,
1265 "select_range_check": 0,
1266 "select_scan": 2,
1267 "slow_queries": 0,
1268 "sort_merge_passes": 0,
1269 "sort_range": 0,
1270 "sort_scan": 0,
1271 "table_locks_immediate": 60,
1272 "table_locks_waited": 0,
1273 "table_open_cache": 2000,
1274 "table_open_cache_overflows": 0,
1275 "thread_cache_misses": 1666,
1276 "threads_cached": 0,
1277 "threads_connected": 1,
1278 "threads_created": 2,
1279 "threads_running": 3,
1280 "userstats_access_denied{user=\"netdata\"}": 33,
1281 "userstats_binlog_bytes_written{user=\"netdata\"}": 0,
1282 "userstats_commit_transactions{user=\"netdata\"}": 0,
1283 "userstats_cpu_time{user=\"netdata\"}": 77,
1284 "userstats_denied_connections{user=\"netdata\"}": 49698,
1285 "userstats_empty_queries{user=\"netdata\"}": 66,
1286 "userstats_lost_connections{user=\"netdata\"}": 0,
1287 "userstats_other_commands{user=\"netdata\"}": 0,
1288 "userstats_rollback_transactions{user=\"netdata\"}": 0,
1289 "userstats_rows_deleted{user=\"netdata\"}": 0,
1290 "userstats_rows_inserted{user=\"netdata\"}": 0,
1291 "userstats_rows_read{user=\"netdata\"}": 0,
1292 "userstats_rows_sent{user=\"netdata\"}": 99,
1293 "userstats_rows_updated{user=\"netdata\"}": 0,
1294 "userstats_select_commands{user=\"netdata\"}": 33,
1295 "userstats_total_connections{user=\"netdata\"}": 1,
1296 "userstats_update_commands{user=\"netdata\"}": 0,
1297 "userstats_access_denied{user=\"root\"}": 0,
1298 "userstats_binlog_bytes_written{user=\"root\"}": 0,
1299 "userstats_commit_transactions{user=\"root\"}": 0,
1300 "userstats_cpu_time{user=\"root\"}": 0,
1301 "userstats_denied_connections{user=\"root\"}": 0,
1302 "userstats_empty_queries{user=\"root\"}": 0,
1303 "userstats_lost_connections{user=\"root\"}": 0,
1304 "userstats_other_commands{user=\"root\"}": 0,
1305 "userstats_rollback_transactions{user=\"root\"}": 0,
1306 "userstats_rows_deleted{user=\"root\"}": 0,
1307 "userstats_rows_inserted{user=\"root\"}": 0,
1308 "userstats_rows_read{user=\"root\"}": 0,
1309 "userstats_rows_sent{user=\"root\"}": 2,
1310 "userstats_rows_updated{user=\"root\"}": 0,
1311 "userstats_select_commands{user=\"root\"}": 0,
1312 "userstats_total_connections{user=\"root\"}": 1,
1313 "userstats_update_commands{user=\"root\"}": 0,
1314 }
1315
1316 copyProcessListQueryDuration(mx, expected)
1317 assertExpectedMetrics(t, mx, expected)
1318 },
1319 },
1320 },
1321 "MariaDB-GaleraCluster[v10.8.4]: success on all queries": {
1322 {
1323 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
1324 mockExpect(t, m, queryShowVersion, dataMariaGaleraClusterVer1084Version)
1325 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
1326 mockExpect(t, m, queryDisableSessionQueryLog, nil)
1327 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
1328 mockExpect(t, m, queryShowGlobalStatus, dataMariaGaleraClusterVer1084GlobalStatus)
1329 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMariaGaleraClusterVer1084EngineInnoDBStatus)
1330 mockExpect(t, m, queryShowGlobalVariables, dataMariaGaleraClusterVer1084GlobalVariables)
1331 mockExpect(t, m, queryShowAllSlavesStatus, nil)
1332 mockExpect(t, m, queryShowUserStatistics, dataMariaGaleraClusterVer1084UserStatistics)
1333 mockExpect(t, m, queryShowProcessList, dataMariaGaleraClusterVer1084ProcessList)
1334 },
1335 check: func(t *testing.T, collr *Collector) {
1336 collr.galeraDetected = true
1337 mx, err := collecttest.CollectScalarSeries(collr)
1338 require.NoError(t, err)
1339
1340 expected := map[string]metrix.SampleValue{
1341 "aborted_connects": 0,
1342 "binlog_cache_disk_use": 0,
1343 "binlog_cache_use": 0,
1344 "binlog_stmt_cache_disk_use": 0,
1345 "binlog_stmt_cache_use": 0,
1346 "bytes_received": 3009,
1347 "bytes_sent": 228856,
1348 "com_delete": 6,
1349 "com_insert": 0,
1350 "com_replace": 0,
1351 "com_select": 12,
1352 "com_update": 0,
1353 "connection_errors_accept": 0,
1354 "connection_errors_internal": 0,
1355 "connection_errors_max_connections": 0,
1356 "connection_errors_peer_address": 0,
1357 "connection_errors_select": 0,
1358 "connection_errors_tcpwrap": 0,
1359 "connections": 15,
1360 "created_tmp_disk_tables": 4,
1361 "created_tmp_files": 5,
1362 "created_tmp_tables": 17,
1363 "handler_commit": 37,
1364 "handler_delete": 7,
1365 "handler_prepare": 0,
1366 "handler_read_first": 3,
1367 "handler_read_key": 9,
1368 "handler_read_next": 1,
1369 "handler_read_prev": 0,
1370 "handler_read_rnd": 0,
1371 "handler_read_rnd_next": 6222,
1372 "handler_rollback": 0,
1373 "handler_savepoint": 0,
1374 "handler_savepoint_rollback": 0,
1375 "handler_update": 0,
1376 "handler_write": 9,
1377 "innodb_buffer_pool_bytes_data": 5193728,
1378 "innodb_buffer_pool_bytes_dirty": 2260992,
1379 "innodb_buffer_pool_pages_data": 317,
1380 "innodb_buffer_pool_pages_dirty": 138,
1381 "innodb_buffer_pool_pages_flushed": 0,
1382 "innodb_buffer_pool_pages_free": 7747,
1383 "innodb_buffer_pool_pages_misc": 0,
1384 "innodb_buffer_pool_pages_total": 8064,
1385 "innodb_buffer_pool_read_ahead": 0,
1386 "innodb_buffer_pool_read_ahead_evicted": 0,
1387 "innodb_buffer_pool_read_ahead_rnd": 0,
1388 "innodb_buffer_pool_read_requests": 2298,
1389 "innodb_buffer_pool_reads": 184,
1390 "innodb_buffer_pool_wait_free": 0,
1391 "innodb_buffer_pool_write_requests": 203,
1392 "innodb_checkpoint_age": 6745,
1393 "innodb_data_fsyncs": 15,
1394 "innodb_data_pending_fsyncs": 0,
1395 "innodb_data_pending_reads": 0,
1396 "innodb_data_pending_writes": 0,
1397 "innodb_data_read": 3014656,
1398 "innodb_data_reads": 201,
1399 "innodb_data_writes": 14,
1400 "innodb_data_written": 0,
1401 "innodb_deadlocks": 0,
1402 "innodb_last_checkpoint_at": 46617,
1403 "innodb_log_file_size": 100663296,
1404 "innodb_log_files_in_group": 1,
1405 "innodb_log_group_capacity": 100663296,
1406 "innodb_log_occupancy": 6,
1407 "innodb_log_sequence_number": 53362,
1408 "innodb_log_waits": 0,
1409 "innodb_log_write_requests": 65,
1410 "innodb_log_writes": 13,
1411 "innodb_os_log_written": 4785,
1412 "innodb_row_lock_current_waits": 0,
1413 "innodb_rows_deleted": 0,
1414 "innodb_rows_inserted": 0,
1415 "innodb_rows_read": 0,
1416 "innodb_rows_updated": 0,
1417 "key_blocks_not_flushed": 0,
1418 "key_blocks_unused": 107163,
1419 "key_blocks_used": 0,
1420 "key_read_requests": 0,
1421 "key_reads": 0,
1422 "key_write_requests": 0,
1423 "key_writes": 0,
1424 "max_connections": 151,
1425 "max_used_connections": 1,
1426 "open_files": 7,
1427 "open_tables": 0,
1428 "opened_files": 125,
1429 "opened_tables": 24,
1430 "process_list_fetch_query_duration": 0,
1431 "process_list_longest_query_duration": 9,
1432 "process_list_queries_count_system": 0,
1433 "process_list_queries_count_user": 2,
1434 "qcache_free_blocks": 1,
1435 "qcache_free_memory": 1031272,
1436 "qcache_hits": 0,
1437 "qcache_inserts": 0,
1438 "qcache_lowmem_prunes": 0,
1439 "qcache_not_cached": 0,
1440 "qcache_queries_in_cache": 0,
1441 "qcache_total_blocks": 1,
1442 "queries": 75,
1443 "questions": 62,
1444 "select_full_join": 0,
1445 "select_full_range_join": 0,
1446 "select_range": 0,
1447 "select_range_check": 0,
1448 "select_scan": 17,
1449 "slow_queries": 0,
1450 "sort_merge_passes": 0,
1451 "sort_range": 0,
1452 "sort_scan": 0,
1453 "table_locks_immediate": 17,
1454 "table_locks_waited": 0,
1455 "table_open_cache": 2000,
1456 "table_open_cache_overflows": 0,
1457 "thread_cache_misses": 4000,
1458 "threads_cached": 0,
1459 "threads_connected": 1,
1460 "threads_created": 6,
1461 "threads_running": 1,
1462 "userstats_access_denied{user=\"netdata\"}": 33,
1463 "userstats_binlog_bytes_written{user=\"netdata\"}": 0,
1464 "userstats_commit_transactions{user=\"netdata\"}": 0,
1465 "userstats_cpu_time{user=\"netdata\"}": 77,
1466 "userstats_denied_connections{user=\"netdata\"}": 49698,
1467 "userstats_empty_queries{user=\"netdata\"}": 66,
1468 "userstats_lost_connections{user=\"netdata\"}": 0,
1469 "userstats_other_commands{user=\"netdata\"}": 0,
1470 "userstats_rollback_transactions{user=\"netdata\"}": 0,
1471 "userstats_rows_deleted{user=\"netdata\"}": 0,
1472 "userstats_rows_inserted{user=\"netdata\"}": 0,
1473 "userstats_rows_read{user=\"netdata\"}": 0,
1474 "userstats_rows_sent{user=\"netdata\"}": 99,
1475 "userstats_rows_updated{user=\"netdata\"}": 0,
1476 "userstats_select_commands{user=\"netdata\"}": 33,
1477 "userstats_total_connections{user=\"netdata\"}": 1,
1478 "userstats_update_commands{user=\"netdata\"}": 0,
1479 "userstats_access_denied{user=\"root\"}": 0,
1480 "userstats_binlog_bytes_written{user=\"root\"}": 0,
1481 "userstats_commit_transactions{user=\"root\"}": 0,
1482 "userstats_cpu_time{user=\"root\"}": 0,
1483 "userstats_denied_connections{user=\"root\"}": 0,
1484 "userstats_empty_queries{user=\"root\"}": 0,
1485 "userstats_lost_connections{user=\"root\"}": 0,
1486 "userstats_other_commands{user=\"root\"}": 0,
1487 "userstats_rollback_transactions{user=\"root\"}": 0,
1488 "userstats_rows_deleted{user=\"root\"}": 0,
1489 "userstats_rows_inserted{user=\"root\"}": 0,
1490 "userstats_rows_read{user=\"root\"}": 0,
1491 "userstats_rows_sent{user=\"root\"}": 2,
1492 "userstats_rows_updated{user=\"root\"}": 0,
1493 "userstats_select_commands{user=\"root\"}": 0,
1494 "userstats_total_connections{user=\"root\"}": 1,
1495 "userstats_update_commands{user=\"root\"}": 0,
1496 "wsrep_cluster_size": 3,
1497 "wsrep_cluster_weight": 3,
1498 "wsrep_connected": 1,
1499 "wsrep_flow_control_paused_ns": 0,
1500 "wsrep_local_bf_aborts": 0,
1501 "wsrep_local_cert_failures": 0,
1502 "wsrep_local_recv_queue": 0,
1503 "wsrep_local_send_queue": 0,
1504 "wsrep_open_transactions": 0,
1505 "wsrep_ready": 1,
1506 "wsrep_received": 11,
1507 "wsrep_received_bytes": 1410,
1508 "wsrep_replicated": 0,
1509 "wsrep_replicated_bytes": 0,
1510 "wsrep_thread_count": 5,
1511 }
1512
1513 copyProcessListQueryDuration(mx, expected)
1514 assertExpectedMetrics(t, mx, expected)
1515 collecttest.AssertChartCoverage(t, collr, collecttest.ChartCoverageExpectation{
1516 ExcludeContextPatterns: []string{
1517 "mysql.slave_*",
1518 },
1519 RequiredContexts: map[string][]string{
1520 "mysql.galera_cluster_status": {"disconnected", "non_primary", "primary"},
1521 "mysql.galera_cluster_state": {"donor", "error", "joined", "joining", "synced", "undefined"},
1522 },
1523 })
1524 },
1525 },
1526 },
1527 "MySQL-MultiSourceReplication[v8.0.30]: success on all queries": {
1528 {
1529 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
1530 mockExpect(t, m, queryShowVersion, dataMySQLVer8030Version)
1531 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
1532 mockExpect(t, m, queryDisableSessionQueryLog, nil)
1533 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
1534 mockExpect(t, m, queryShowGlobalStatus, dataMySQLVer8030GlobalStatus)
1535 mockExpect(t, m, queryShowEngineInnoDBStatus, dataMySQLVer8030EngineInnoDBStatus)
1536 mockExpect(t, m, queryShowGlobalVariables, dataMySQLVer8030GlobalVariables)
1537 mockExpect(t, m, queryShowReplicaStatus, dataMySQLVer8030ReplicaStatusMultiSource)
1538 mockExpect(t, m, queryShowProcessListPS, dataMySQLVer8030ProcessList)
1539 },
1540 check: func(t *testing.T, collr *Collector) {
1541 mx, err := collecttest.CollectScalarSeries(collr)
1542 require.NoError(t, err)
1543
1544 expected := map[string]metrix.SampleValue{
1545 "aborted_connects": 0,
1546 "binlog_cache_disk_use": 0,
1547 "binlog_cache_use": 6,
1548 "binlog_stmt_cache_disk_use": 0,
1549 "binlog_stmt_cache_use": 0,
1550 "bytes_received": 5584,
1551 "bytes_sent": 70700,
1552 "com_delete": 0,
1553 "com_insert": 0,
1554 "com_replace": 0,
1555 "com_select": 2,
1556 "com_update": 0,
1557 "connection_errors_accept": 0,
1558 "connection_errors_internal": 0,
1559 "connection_errors_max_connections": 0,
1560 "connection_errors_peer_address": 0,
1561 "connection_errors_select": 0,
1562 "connection_errors_tcpwrap": 0,
1563 "connections": 25,
1564 "created_tmp_disk_tables": 0,
1565 "created_tmp_files": 5,
1566 "created_tmp_tables": 6,
1567 "handler_commit": 720,
1568 "handler_delete": 8,
1569 "handler_prepare": 24,
1570 "handler_read_first": 50,
1571 "handler_read_key": 1914,
1572 "handler_read_next": 4303,
1573 "handler_read_prev": 0,
1574 "handler_read_rnd": 0,
1575 "handler_read_rnd_next": 4723,
1576 "handler_rollback": 1,
1577 "handler_savepoint": 0,
1578 "handler_savepoint_rollback": 0,
1579 "handler_update": 373,
1580 "handler_write": 1966,
1581 "innodb_buffer_pool_bytes_data": 17121280,
1582 "innodb_buffer_pool_bytes_dirty": 0,
1583 "innodb_buffer_pool_pages_data": 1045,
1584 "innodb_buffer_pool_pages_dirty": 0,
1585 "innodb_buffer_pool_pages_flushed": 361,
1586 "innodb_buffer_pool_pages_free": 7143,
1587 "innodb_buffer_pool_pages_misc": 4,
1588 "innodb_buffer_pool_pages_total": 8192,
1589 "innodb_buffer_pool_read_ahead": 0,
1590 "innodb_buffer_pool_read_ahead_evicted": 0,
1591 "innodb_buffer_pool_read_ahead_rnd": 0,
1592 "innodb_buffer_pool_read_requests": 16723,
1593 "innodb_buffer_pool_reads": 878,
1594 "innodb_buffer_pool_wait_free": 0,
1595 "innodb_buffer_pool_write_requests": 2377,
1596 "innodb_checkpoint_age": 0,
1597 "innodb_data_fsyncs": 255,
1598 "innodb_data_pending_fsyncs": 0,
1599 "innodb_data_pending_reads": 0,
1600 "innodb_data_pending_writes": 0,
1601 "innodb_data_read": 14453760,
1602 "innodb_data_reads": 899,
1603 "innodb_data_writes": 561,
1604 "innodb_data_written": 6128128,
1605 "innodb_last_checkpoint_at": 31603995,
1606 "innodb_log_file_size": 50331648,
1607 "innodb_log_files_in_group": 2,
1608 "innodb_log_group_capacity": 100663296,
1609 "innodb_log_occupancy": 0,
1610 "innodb_log_sequence_number": 31603995,
1611 "innodb_log_waits": 0,
1612 "innodb_log_write_requests": 1062,
1613 "innodb_log_writes": 116,
1614 "innodb_os_log_fsyncs": 69,
1615 "innodb_os_log_pending_fsyncs": 0,
1616 "innodb_os_log_pending_writes": 0,
1617 "innodb_os_log_written": 147968,
1618 "innodb_row_lock_current_waits": 0,
1619 "innodb_rows_deleted": 0,
1620 "innodb_rows_inserted": 0,
1621 "innodb_rows_read": 0,
1622 "innodb_rows_updated": 0,
1623 "key_blocks_not_flushed": 0,
1624 "key_blocks_unused": 6698,
1625 "key_blocks_used": 0,
1626 "key_read_requests": 0,
1627 "key_reads": 0,
1628 "key_write_requests": 0,
1629 "key_writes": 0,
1630 "max_connections": 151,
1631 "max_used_connections": 2,
1632 "open_files": 8,
1633 "open_tables": 127,
1634 "opened_files": 8,
1635 "opened_tables": 208,
1636 "process_list_fetch_query_duration": 0,
1637 "process_list_longest_query_duration": 9,
1638 "process_list_queries_count_system": 0,
1639 "process_list_queries_count_user": 2,
1640 "queries": 27,
1641 "questions": 15,
1642 "seconds_behind_master{connection=\"master1\"}": 0,
1643 "seconds_behind_master{connection=\"master2\"}": 0,
1644 "select_full_join": 0,
1645 "select_full_range_join": 0,
1646 "select_range": 0,
1647 "select_range_check": 0,
1648 "select_scan": 12,
1649 "slave_io_running{connection=\"master1\"}": 1,
1650 "slave_io_running{connection=\"master2\"}": 1,
1651 "slave_sql_running{connection=\"master1\"}": 1,
1652 "slave_sql_running{connection=\"master2\"}": 1,
1653 "slow_queries": 0,
1654 "sort_merge_passes": 0,
1655 "sort_range": 0,
1656 "sort_scan": 0,
1657 "table_locks_immediate": 6,
1658 "table_locks_waited": 0,
1659 "table_open_cache": 4000,
1660 "table_open_cache_overflows": 0,
1661 "thread_cache_misses": 800,
1662 "threads_cached": 1,
1663 "threads_connected": 1,
1664 "threads_created": 2,
1665 "threads_running": 2,
1666 }
1667
1668 copyProcessListQueryDuration(mx, expected)
1669 assertExpectedMetrics(t, mx, expected)
1670 },
1671 },
1672 },
1673 "Percona-Standalone[v8.0.29]: success on all queries": {
1674 {
1675 prepareMock: func(t *testing.T, m sqlmock.Sqlmock) {
1676 mockExpect(t, m, queryShowVersion, dataPerconaVer8029Version)
1677 mockExpect(t, m, queryShowSessionVariables, dataSessionVariables)
1678 mockExpect(t, m, queryDisableSessionQueryLog, nil)
1679 mockExpect(t, m, queryDisableSessionSlowQueryLog, nil)
1680 mockExpect(t, m, queryShowGlobalStatus, dataPerconaVer8029GlobalStatus)
1681 mockExpect(t, m, queryShowEngineInnoDBStatus, dataPerconaVer8029EngineInnoDBStatus)
1682 mockExpect(t, m, queryShowGlobalVariables, dataPerconaVer8029GlobalVariables)
1683 mockExpect(t, m, queryShowReplicaStatus, nil)
1684 mockExpect(t, m, queryShowUserStatistics, dataPerconaVer8029UserStatistics)
1685 mockExpect(t, m, queryShowProcessListPS, dataPerconaVer8029ProcessList)
1686 },
1687 check: func(t *testing.T, collr *Collector) {
1688 mx, err := collecttest.CollectScalarSeries(collr)
1689 require.NoError(t, err)
1690
1691 expected := map[string]metrix.SampleValue{
1692 "aborted_connects": 1,
1693 "binlog_cache_disk_use": 0,
1694 "binlog_cache_use": 0,
1695 "binlog_stmt_cache_disk_use": 0,
1696 "binlog_stmt_cache_use": 0,
1697 "bytes_received": 682970,
1698 "bytes_sent": 33668405,
1699 "com_delete": 0,
1700 "com_insert": 0,
1701 "com_replace": 0,
1702 "com_select": 1687,
1703 "com_update": 0,
1704 "connection_errors_accept": 0,
1705 "connection_errors_internal": 0,
1706 "connection_errors_max_connections": 0,
1707 "connection_errors_peer_address": 0,
1708 "connection_errors_select": 0,
1709 "connection_errors_tcpwrap": 0,
1710 "connections": 13,
1711 "created_tmp_disk_tables": 1683,
1712 "created_tmp_files": 5,
1713 "created_tmp_tables": 5054,
1714 "handler_commit": 576,
1715 "handler_delete": 0,
1716 "handler_prepare": 0,
1717 "handler_read_first": 1724,
1718 "handler_read_key": 3439,
1719 "handler_read_next": 4147,
1720 "handler_read_prev": 0,
1721 "handler_read_rnd": 0,
1722 "handler_read_rnd_next": 2983285,
1723 "handler_rollback": 0,
1724 "handler_savepoint": 0,
1725 "handler_savepoint_rollback": 0,
1726 "handler_update": 317,
1727 "handler_write": 906501,
1728 "innodb_buffer_pool_bytes_data": 18399232,
1729 "innodb_buffer_pool_bytes_dirty": 49152,
1730 "innodb_buffer_pool_pages_data": 1123,
1731 "innodb_buffer_pool_pages_dirty": 3,
1732 "innodb_buffer_pool_pages_flushed": 205,
1733 "innodb_buffer_pool_pages_free": 7064,
1734 "innodb_buffer_pool_pages_misc": 5,
1735 "innodb_buffer_pool_pages_total": 8192,
1736 "innodb_buffer_pool_read_ahead": 0,
1737 "innodb_buffer_pool_read_ahead_evicted": 0,
1738 "innodb_buffer_pool_read_ahead_rnd": 0,
1739 "innodb_buffer_pool_read_requests": 109817,
1740 "innodb_buffer_pool_reads": 978,
1741 "innodb_buffer_pool_wait_free": 0,
1742 "innodb_buffer_pool_write_requests": 77412,
1743 "innodb_checkpoint_age": 0,
1744 "innodb_data_fsyncs": 50,
1745 "innodb_data_pending_fsyncs": 0,
1746 "innodb_data_pending_reads": 0,
1747 "innodb_data_pending_writes": 0,
1748 "innodb_data_read": 16094208,
1749 "innodb_data_reads": 1002,
1750 "innodb_data_writes": 288,
1751 "innodb_data_written": 3420160,
1752 "innodb_last_checkpoint_at": 31825026,
1753 "innodb_log_file_size": 50331648,
1754 "innodb_log_files_in_group": 2,
1755 "innodb_log_group_capacity": 100663296,
1756 "innodb_log_occupancy": 0,
1757 "innodb_log_sequence_number": 31825026,
1758 "innodb_log_waits": 0,
1759 "innodb_log_write_requests": 651,
1760 "innodb_log_writes": 47,
1761 "innodb_os_log_fsyncs": 13,
1762 "innodb_os_log_pending_fsyncs": 0,
1763 "innodb_os_log_pending_writes": 0,
1764 "innodb_os_log_written": 45568,
1765 "innodb_row_lock_current_waits": 0,
1766 "innodb_rows_deleted": 0,
1767 "innodb_rows_inserted": 5055,
1768 "innodb_rows_read": 5055,
1769 "innodb_rows_updated": 0,
1770 "key_blocks_not_flushed": 0,
1771 "key_blocks_unused": 6698,
1772 "key_blocks_used": 0,
1773 "key_read_requests": 0,
1774 "key_reads": 0,
1775 "key_write_requests": 0,
1776 "key_writes": 0,
1777 "max_connections": 151,
1778 "max_used_connections": 3,
1779 "open_files": 2,
1780 "open_tables": 77,
1781 "opened_files": 2,
1782 "opened_tables": 158,
1783 "process_list_fetch_query_duration": 0,
1784 "process_list_longest_query_duration": 9,
1785 "process_list_queries_count_system": 0,
1786 "process_list_queries_count_user": 2,
1787 "queries": 6748,
1788 "questions": 6746,
1789 "select_full_join": 0,
1790 "select_full_range_join": 0,
1791 "select_range": 0,
1792 "select_range_check": 0,
1793 "select_scan": 8425,
1794 "slow_queries": 0,
1795 "sort_merge_passes": 0,
1796 "sort_range": 0,
1797 "sort_scan": 1681,
1798 "table_locks_immediate": 3371,
1799 "table_locks_waited": 0,
1800 "table_open_cache": 4000,
1801 "table_open_cache_overflows": 0,
1802 "thread_cache_misses": 2307,
1803 "threads_cached": 1,
1804 "threads_connected": 2,
1805 "threads_created": 3,
1806 "threads_running": 2,
1807 "userstats_access_denied{user=\"netdata\"}": 0,
1808 "userstats_binlog_bytes_written{user=\"netdata\"}": 0,
1809 "userstats_commit_transactions{user=\"netdata\"}": 0,
1810 "userstats_cpu_time{user=\"netdata\"}": 0,
1811 "userstats_denied_connections{user=\"netdata\"}": 0,
1812 "userstats_empty_queries{user=\"netdata\"}": 0,
1813 "userstats_lost_connections{user=\"netdata\"}": 0,
1814 "userstats_other_commands{user=\"netdata\"}": 1,
1815 "userstats_rollback_transactions{user=\"netdata\"}": 0,
1816 "userstats_rows_fetched{user=\"netdata\"}": 1,
1817 "userstats_rows_updated{user=\"netdata\"}": 0,
1818 "userstats_select_commands{user=\"netdata\"}": 1,
1819 "userstats_total_connections{user=\"netdata\"}": 1,
1820 "userstats_update_commands{user=\"netdata\"}": 0,
1821 "userstats_access_denied{user=\"root\"}": 0,
1822 "userstats_binlog_bytes_written{user=\"root\"}": 0,
1823 "userstats_commit_transactions{user=\"root\"}": 0,
1824 "userstats_cpu_time{user=\"root\"}": 151,
1825 "userstats_denied_connections{user=\"root\"}": 1,
1826 "userstats_empty_queries{user=\"root\"}": 36,
1827 "userstats_lost_connections{user=\"root\"}": 0,
1828 "userstats_other_commands{user=\"root\"}": 110,
1829 "userstats_rollback_transactions{user=\"root\"}": 0,
1830 "userstats_rows_fetched{user=\"root\"}": 1,
1831 "userstats_rows_updated{user=\"root\"}": 0,
1832 "userstats_select_commands{user=\"root\"}": 37,
1833 "userstats_total_connections{user=\"root\"}": 2,
1834 "userstats_update_commands{user=\"root\"}": 0,
1835 }
1836
1837 copyProcessListQueryDuration(mx, expected)
1838 assertExpectedMetrics(t, mx, expected)
1839 },
1840 },
1841 },
1842 }
1843
1844 for name, test := range tests {
1845 t.Run(name, func(t *testing.T) {
1846 db, mock, err := sqlmock.New(
1847 sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual),
1848 )
1849 require.NoError(t, err)
1850 collr := New()
1851 collr.db = db
1852 defer func() { _ = db.Close() }()
1853
1854 require.NoError(t, collr.Init(context.Background()))
1855 // Collect tests bypass Check(); enable qcache feature flag so
1856 // expected MariaDB qcache metrics remain validated in this suite.
1857 collr.qcacheDetected = true
1858
1859 for i, step := range test {
1860 t.Run(fmt.Sprintf("step[%d]", i), func(t *testing.T) {
1861 step.prepareMock(t, mock)
1862 step.check(t, collr)
1863 })
1864 }
1865 assert.NoError(t, mock.ExpectationsWereMet())
1866 })
1867 }
1868 }
1869
1870 func assertExpectedMetrics(t *testing.T, actual map[string]metrix.SampleValue, expected map[string]metrix.SampleValue) {
1871 t.Helper()
1872 require.Equal(t, expected, actual)
1873 }
1874
1875 func copyProcessListQueryDuration(actual map[string]metrix.SampleValue, expected map[string]metrix.SampleValue) {
1876 v, ok := actual["process_list_fetch_query_duration"]
1877 if !ok {
1878 return
1879 }
1880 if _, ok := expected["process_list_fetch_query_duration"]; !ok {
1881 return
1882 }
1883 expected["process_list_fetch_query_duration"] = v
1884 }
1885
1886 func mustMockRows(t *testing.T, data []byte) *sqlmock.Rows {
1887 rows, err := prepareMockRows(data)
1888 require.NoError(t, err)
1889 return rows
1890 }
1891
1892 func mockExpect(t *testing.T, mock sqlmock.Sqlmock, query string, rows []byte) {
1893 mock.ExpectQuery(query).WillReturnRows(mustMockRows(t, rows)).RowsWillBeClosed()
1894 }
1895
1896 func mockExpectErr(mock sqlmock.Sqlmock, query string) {
1897 mock.ExpectQuery(query).WillReturnError(fmt.Errorf("mock error (%s)", query))
1898 }
1899
1900 func TestPrepareMockRows(t *testing.T) {
1901 tests := map[string]struct {
1902 data string
1903 rows *sqlmock.Rows
1904 }{
1905 "one row": {
1906 data: `
1907 +------+-------+
1908 | Name | Value |
1909 +------+-------+
1910 | a | 1 |
1911 +------+-------+
1912 `,
1913 rows: sqlmock.NewRows([]string{"Name", "Value"}).
1914 AddRow("a", "1"),
1915 },
1916 "two rows": {
1917 data: `
1918 +------+-------+
1919 | Name | Value |
1920 +------+-------+
1921 | a | 1 |
1922 | b | 2 |
1923 +------+-------+
1924 `,
1925 rows: sqlmock.NewRows([]string{"Name", "Value"}).
1926 AddRow("a", "1").AddRow("b", "2"),
1927 },
1928 "multiline text": {
1929 data: `
1930 +------+-------+
1931 | Name | Value |
1932 +------+-------+
1933 | a | b
1934 c d
1935 e |
1936 +------+-------+
1937 `,
1938 rows: sqlmock.NewRows([]string{"Name", "Value"}).
1939 AddRow("a", "b\nc d\ne"),
1940 },
1941 "multiline text prefixed and suffixed with \\n": {
1942 data: `
1943 +------+-------+
1944 | Name | Value |
1945 +------+-------+
1946 | a |
1947 b c
1948 d
1949 |
1950 +------+-------+
1951 `,
1952 rows: sqlmock.NewRows([]string{"Name", "Value"}).
1953 AddRow("a", "\nb c\nd\n"),
1954 },
1955 "multiline text in the first column": {
1956 data: `
1957 +-------+------+
1958 | Value | Name |
1959 +-------+------+
1960 | a
1961 b c
1962 d
1963 | e |
1964 +-------+------+
1965 `,
1966 rows: sqlmock.NewRows([]string{"Value", "Name"}).
1967 AddRow("a\nb c\nd\n", "e"),
1968 }}
1969
1970 for name, test := range tests {
1971 t.Run(name, func(t *testing.T) {
1972 out, err := prepareMockRows([]byte(test.data))
1973 assert.NoError(t, err)
1974 assert.Equal(t, test.rows, out)
1975 })
1976 }
1977 }
1978
1979 func prepareMockRows(data []byte) (*sqlmock.Rows, error) {
1980 if len(data) == 0 {
1981 return sqlmock.NewRows(nil), nil
1982 }
1983
1984 r := bytes.NewReader(data)
1985 sc := bufio.NewScanner(r)
1986
1987 var numColumns int
1988 var rows *sqlmock.Rows
1989 var rowLines []string
1990
1991 for sc.Scan() {
1992 line := sc.Text()
1993 s := strings.TrimSpace(line)
1994 switch {
1995 case s == "",
1996 strings.HasPrefix(s, "+"),
1997 strings.HasPrefix(s, "ft_boolean_syntax"):
1998 continue
1999 }
2000
2001 if rows == nil {
2002 parts := splitCells(line)
2003 numColumns = len(parts)
2004 rows = sqlmock.NewRows(parts)
2005 continue
2006 }
2007
2008 if strings.Count(s, "|")-1 == numColumns || (rowLines != nil && strings.HasSuffix(s, "|")) {
2009 vals, err := buildRow(append(rowLines, line), numColumns)
2010 if err != nil {
2011 return nil, err
2012 }
2013 rows.AddRow(vals...)
2014 rowLines = nil
2015 continue
2016 }
2017
2018 rowLines = append(rowLines, line)
2019 }
2020
2021 if rows == nil {
2022 return nil, errors.New("prepareMockRows(): nil rows result")
2023 }
2024
2025 return rows, sc.Err()
2026 }
2027
2028 func splitCells(s string) []string {
2029 parts := strings.Split(strings.Trim(s, "|"), "|")
2030 for i := range parts {
2031 parts[i] = strings.TrimSpace(parts[i])
2032 }
2033 return parts
2034 }
2035
2036 func buildRow(lines []string, cols int) ([]driver.Value, error) {
2037 row := strings.Join(lines, "\n")
2038 if !strings.HasPrefix(row, "|") || !strings.HasSuffix(row, "|") {
2039 return nil, errors.New("prepareMockRows(): malformed row")
2040 }
2041
2042 parts := strings.Split(strings.Trim(row, "|"), "|")
2043 if len(parts) != cols {
2044 return nil, fmt.Errorf("prepareMockRows(): columns != values (%d/%d)", cols, len(parts))
2045 }
2046
2047 vals := make([]driver.Value, cols)
2048 for i, c := range parts {
2049 vals[i] = strings.Trim(c, " ")
2050 }
2051 return vals, nil
2052 }