From 9b4ef8f9a5e90cad69398ffde716464ea3300176 Mon Sep 17 00:00:00 2001 From: ColdWaterLW Date: Thu, 23 Jul 2020 17:05:03 +0800 Subject: [PATCH 1/5] add items "read_only" and "server_id" --- actiontech_mysql_monitor.go | 2 + actiontech_zbx_3.4_template_mysql_server.xml | 84 ++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/actiontech_mysql_monitor.go b/actiontech_mysql_monitor.go index f08a0ef..4c66e4d 100644 --- a/actiontech_mysql_monitor.go +++ b/actiontech_mysql_monitor.go @@ -726,6 +726,8 @@ func print(result map[string]string, fp *os.File) { "query_rt1ms", "query_rtavg", "query_avgrt", + "read_only", + "server_id", } // Return the output. diff --git a/actiontech_zbx_3.4_template_mysql_server.xml b/actiontech_zbx_3.4_template_mysql_server.xml index b9632b1..42efe8a 100644 --- a/actiontech_zbx_3.4_template_mysql_server.xml +++ b/actiontech_zbx_3.4_template_mysql_server.xml @@ -8894,6 +8894,90 @@ + + MySQL read only on $1 + 0 + + + MySQL.[{#MYSQLPORT},read_only] + 30s + 90d + 365d + 0 + 4 + + + + + 0 + 0 + + 0 + + + + 0 + + + + + + MySQL read only + 0 + + + MySQL + + + + + + + + + + + MySQL server id on $1 + 0 + + + MySQL.[{#MYSQLPORT},server_id] + 30s + 90d + 365d + 0 + 3 + + + + + 0 + 0 + + 0 + + + + 0 + + + + + + MySQL server id + 0 + + + MySQL + + + + + + + + + Table Cache on $1 0 From cf36bdf4a2ea2ca7c876cf0248a6d9171b421ac1 Mon Sep 17 00:00:00 2001 From: ColdWaterLW Date: Thu, 23 Jul 2020 17:06:31 +0800 Subject: [PATCH 2/5] 1. filter unimportant records before sorting time; 2. collect only top three time from show processlist --- actiontech_mysql_monitor.go | 13 +- actiontech_zbx_3.4_template_mysql_server.xml | 300 +------------------ 2 files changed, 13 insertions(+), 300 deletions(-) diff --git a/actiontech_mysql_monitor.go b/actiontech_mysql_monitor.go index 4c66e4d..544e5b4 100644 --- a/actiontech_mysql_monitor.go +++ b/actiontech_mysql_monitor.go @@ -233,11 +233,18 @@ func collect() ([]bool, []map[string]string) { log.Println("collectionInfo master : ", collectionInfo[SHOW_MASTER_LOGS]) } - // Get SHOW PROCESSLIST and aggregate it by state, sort by time + // Get SHOW PROCESSLIST and aggregate it by state, sort by time with filter if *procs { collectionExist[SHOW_PROCESSLIST] = true - collectionInfo[SHOW_PROCESSLIST] = collectMultiColumnAllRowsAsMapValue([]string{SHOW_PROCESSLIST_STATE_PRE, SHOW_PROCESSLIST_TIME_PRE}, - []string{"state", "time"}, db, "SHOW PROCESSLIST") + collectionInfo[SHOW_PROCESSLIST] = make(map[string]string) + stateCollection := collectMultiColumnAllRowsAsMapValue([]string{SHOW_PROCESSLIST_STATE_PRE}, + []string{"state"}, db, "SHOW PROCESSLIST") + + timeCollection := collectMultiColumnAllRowsAsMapValue([]string{SHOW_PROCESSLIST_TIME_PRE}, + []string{"time"}, db, "SELECT time FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state NOT IN ('','sleep') AND user NOT IN ('root','repl') AND db != 'NULL'") + stringMapAdd(collectionInfo[SHOW_PROCESSLIST], stateCollection) + stringMapAdd(collectionInfo[SHOW_PROCESSLIST], timeCollection) + log.Println("collectionInfo show processlist:", collectionInfo[SHOW_PROCESSLIST]) } diff --git a/actiontech_zbx_3.4_template_mysql_server.xml b/actiontech_zbx_3.4_template_mysql_server.xml index 42efe8a..fc945d8 100644 --- a/actiontech_zbx_3.4_template_mysql_server.xml +++ b/actiontech_zbx_3.4_template_mysql_server.xml @@ -8502,7 +8502,7 @@ - Process list time top 1 + Process list time top 1 with filter 0 @@ -8544,7 +8544,7 @@ - Process list time top 2 + Process list time top 2 with filter 0 @@ -8586,301 +8586,7 @@ - Process list time top 3 - 0 - - - MySQL - - - - - - - - - - - Process list time top 4 on $1 - 0 - - - MySQL.[{#MYSQLPORT},Time_top_4] - 30s - 90d - 365d - 0 - 0 - - - - - 0 - 0 - - 0 - - - - 0 - - - - - - Process list time top 4 - 0 - - - MySQL - - - - - - - - - - - Process list time top 5 on $1 - 0 - - - MySQL.[{#MYSQLPORT},Time_top_5] - 30s - 90d - 365d - 0 - 0 - - - - - 0 - 0 - - 0 - - - - 0 - - - - - - Process list time top 5 - 0 - - - MySQL - - - - - - - - - - - Process list time top 6 on $1 - 0 - - - MySQL.[{#MYSQLPORT},Time_top_6] - 30s - 90d - 365d - 0 - 0 - - - - - 0 - 0 - - 0 - - - - 0 - - - - - - Process list time top 6 - 0 - - - MySQL - - - - - - - - - - - Process list time top 7 on $1 - 0 - - - MySQL.[{#MYSQLPORT},Time_top_7] - 30s - 90d - 365d - 0 - 0 - - - - - 0 - 0 - - 0 - - - - 0 - - - - - - Process list time top 7 - 0 - - - MySQL - - - - - - - - - - - Process list time top 8 on $1 - 0 - - - MySQL.[{#MYSQLPORT},Time_top_8] - 30s - 90d - 365d - 0 - 0 - - - - - 0 - 0 - - 0 - - - - 0 - - - - - - Process list time top 8 - 0 - - - MySQL - - - - - - - - - - - Process list time top 9 on $1 - 0 - - - MySQL.[{#MYSQLPORT},Time_top_9] - 30s - 90d - 365d - 0 - 0 - - - - - 0 - 0 - - 0 - - - - 0 - - - - - - Process list time top 9 - 0 - - - MySQL - - - - - - - - - - - Process list time top 10 on $1 - 0 - - - MySQL.[{#MYSQLPORT},Time_top_10] - 30s - 90d - 365d - 0 - 0 - - - - - 0 - 0 - - 0 - - - - 0 - - - - - - Process list time top 10 + Process list time top 3 with filter 0 From 505e87ef1611c36fca9b81a6046230c50eb64a39 Mon Sep 17 00:00:00 2001 From: ColdWaterLW Date: Thu, 23 Jul 2020 17:07:49 +0800 Subject: [PATCH 3/5] add items to monitor duration of transaction uncommitted in mysql --- actiontech_mysql_monitor.go | 56 +++++++-- actiontech_zbx_3.4_template_mysql_server.xml | 126 +++++++++++++++++++ 2 files changed, 172 insertions(+), 10 deletions(-) diff --git a/actiontech_mysql_monitor.go b/actiontech_mysql_monitor.go index 544e5b4..81c60aa 100644 --- a/actiontech_mysql_monitor.go +++ b/actiontech_mysql_monitor.go @@ -27,12 +27,14 @@ const ( SHOW_INNODB_STATUS SELECT_FROM_QUERY_RESPONSE_TIME_PERCONA SELECT_FROM_QUERY_RESPONSE_TIME_MYSQL + SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL ) // pre key const ( - SHOW_PROCESSLIST_STATE_PRE = "show_processlist_state_" - SHOW_PROCESSLIST_TIME_PRE = "show_processlist_time_" + SHOW_PROCESSLIST_STATE_PRE = "show_processlist_state_" + SHOW_PROCESSLIST_TIME_PRE = "show_processlist_time_" + SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL_PRE = "select_from_uncommitted_trx_duration_" ) var ( @@ -61,6 +63,7 @@ var ( procs = flag.Bool("procs", true, "Whether to check SHOW PROCESSLIST") getQrtPercona = flag.Bool("get_qrt_percona", true, "Whether to get response times from Percona Server or MariaDB") getQrtMysql = flag.Bool("get_qrt_mysql", false, "Whether to get response times from MySQL (default: false)") + getUcTrxDurMysql = flag.Bool("get_uctrx_dur_mysql", true, "Whether to get uncommitted transaction duration from MySQL (default: false)") discoveryPort = flag.Bool("discovery_port", false, "`discovery mysqld port`, print in json format (default: false)") useSudo = flag.Bool("sudo", true, "Use `sudo netstat...`") version = flag.Bool("version", false, "print version") @@ -170,8 +173,8 @@ func collect() ([]bool, []map[string]string) { } // Collecting ... - collectionInfo := make([]map[string]string, 8) - collectionExist := []bool{true, true, false, false, false, false, false, false} + collectionInfo := make([]map[string]string, 9) + collectionExist := []bool{true, true, false, false, false, false, false, false, true} collectionInfo[SHOW_STATUS] = collectAllRowsToMap("variable_name", "value", db, "SHOW /*!50002 GLOBAL */ STATUS") collectionInfo[SHOW_VARIABLES] = collectAllRowsToMap("variable_name", "value", db, "SHOW VARIABLES") @@ -285,6 +288,12 @@ SELECT 'query_rt100us', ifnull(sum(COUNT_STAR),0) as cnt FROM performance_schema stringMapAdd(collectionInfo[SELECT_FROM_QUERY_RESPONSE_TIME_MYSQL], collectFirstRowAsMapValue("query_avgrt", "avgrt", db, "select round(avg(AVG_TIMER_WAIT)/1000/1000/1000,2) as avgrt from performance_schema.events_statements_summary_by_digest")) } + if *getUcTrxDurMysql { + collectionExist[SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL] = true + collectionInfo[SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL] = collectMultiColumnAllRowsAsMapValue([]string{SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL_PRE}, []string{"time"}, db, "SELECT p.time FROM information_schema.innodb_trx t INNER JOIN information_schema.processlist p ON t.trx_mysql_thread_id = p.id WHERE t.trx_state = 'RUNNING' AND p.time > 10 AND p.command = 'Sleep'") + log.Println("collectionInfo uncommitted trx duration:", collectionInfo[SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL]) + } + return collectionExist, collectionInfo } @@ -431,12 +440,7 @@ func parse(collectionExist []bool, collectionInfo []map[string]string) map[strin } } - sort.Sort(sort.Reverse(sort.IntSlice(procsTimeSort))) - for i, t := range procsTimeSort { - if _, ok := procsTimeMap["Time_top_"+strconv.Itoa(i+1)]; ok { - procsTimeMap["Time_top_"+strconv.Itoa(i+1)] = int64(t) - } - } + putTopInfoIntoMap("Time_top_", procsTimeSort, procsTimeMap) intMapAdd(stat, procsStateMap) intMapAdd(stat, procsTimeMap) @@ -497,10 +501,39 @@ func parse(collectionExist []bool, collectionInfo []map[string]string) map[strin stringMapAdd(stat, collectionInfo[SELECT_FROM_QUERY_RESPONSE_TIME_MYSQL]) } + if collectionExist[SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL] { + timeMap := map[string]int64{ + "uncommitted_trx_duration_top_1": 0, + "uncommitted_trx_duration_top_2": 0, + "uncommitted_trx_duration_top_3": 0, + } + + timeSort := []int{} + for _, value := range collectionInfo[SELECT_FROM_UNCOMMITTED_TRX_DURATION_MYSQL] { + time, err := strconv.Atoi(value) + if nil != err { + log.Printf("select from uncommitted transaction duration: convert time %v error %v\n", value, err) + } + timeSort = append(timeSort, time) + } + + putTopInfoIntoMap("uncommitted_trx_duration_top_", timeSort, timeMap) + intMapAdd(stat, timeMap) + } + return stat } +func putTopInfoIntoMap(keyPrefix string, srcInfo []int, targetMap map[string]int64) { + sort.Sort(sort.Reverse(sort.IntSlice(srcInfo))) + for i, t := range srcInfo { + if _, ok := targetMap[keyPrefix+strconv.Itoa(i+1)]; ok { + targetMap[keyPrefix+strconv.Itoa(i+1)] = int64(t) + } + } +} + func print(result map[string]string, fp *os.File) { // Define the variables to output. key := []string{ @@ -735,6 +768,9 @@ func print(result map[string]string, fp *os.File) { "query_avgrt", "read_only", "server_id", + "uncommitted_trx_duration_top_1", + "uncommitted_trx_duration_top_2", + "uncommitted_trx_duration_top_3", } // Return the output. diff --git a/actiontech_zbx_3.4_template_mysql_server.xml b/actiontech_zbx_3.4_template_mysql_server.xml index fc945d8..9163204 100644 --- a/actiontech_zbx_3.4_template_mysql_server.xml +++ b/actiontech_zbx_3.4_template_mysql_server.xml @@ -8684,6 +8684,132 @@ + + MySQL uncommitted TRX duration top 1 on $1 + 0 + + + MySQL.[{#MYSQLPORT},uncommitted_trx_duration_top_1] + 30s + 90d + 365d + 0 + 3 + + + + + 0 + 0 + + 0 + + + + 0 + + + + + + MySQL uncommitted TRX duration top 1 + 0 + + + MySQL + + + + + + + + + + + MySQL uncommitted TRX duration top 2 on $1 + 0 + + + MySQL.[{#MYSQLPORT},uncommitted_trx_duration_top_2] + 30s + 90d + 365d + 0 + 3 + + + + + 0 + 0 + + 0 + + + + 0 + + + + + + MySQL uncommitted TRX duration top 2 + 0 + + + MySQL + + + + + + + + + + + MySQL uncommitted TRX duration top 3 on $1 + 0 + + + MySQL.[{#MYSQLPORT},uncommitted_trx_duration_top_3] + 30s + 90d + 365d + 0 + 3 + + + + + 0 + 0 + + 0 + + + + 0 + + + + + + MySQL uncommitted TRX duration top 3 + 0 + + + MySQL + + + + + + + + + Table Cache on $1 0 From 83088144ee2df4965e8a76f44be38474b3bc2af9 Mon Sep 17 00:00:00 2001 From: ColdWaterLW Date: Thu, 23 Jul 2020 17:08:52 +0800 Subject: [PATCH 4/5] update items in readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index fb616f0..096b3d9 100644 --- a/README.md +++ b/README.md @@ -407,6 +407,12 @@ relay_log_space: 取所有通道的relay_log_space的和 | query_rt10ms| performance_schema.events_statements_summary_by_digest| | query_rt1ms|performance_schema.events_statements_summary_by_digest| | query_avgrt |performance_schema.events_statements_summary_by_digest| +| read_only | SHOW /*!50002 GLOBAL */ STATUS| +| server_id | SHOW VARIABLES| +| uncommitted_trx_duration_top_1 |information_schema.processlist and information_schema.innodb_trx| +| uncommitted_trx_duration_top_2 |information_schema.processlist and information_schema.innodb_trx| +| uncommitted_trx_duration_top_3 |information_schema.processlist and information_schema.innodb_trx| + From 1d0096d0d91a4a65b18cbae13a5d1f5939ac35e7 Mon Sep 17 00:00:00 2001 From: ColdWaterLW Date: Fri, 24 Jul 2020 13:47:33 +0800 Subject: [PATCH 5/5] fix default value and SQL --- README.md | 2 +- actiontech_mysql_monitor.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 096b3d9..6eca61f 100644 --- a/README.md +++ b/README.md @@ -407,7 +407,7 @@ relay_log_space: 取所有通道的relay_log_space的和 | query_rt10ms| performance_schema.events_statements_summary_by_digest| | query_rt1ms|performance_schema.events_statements_summary_by_digest| | query_avgrt |performance_schema.events_statements_summary_by_digest| -| read_only | SHOW /*!50002 GLOBAL */ STATUS| +| read_only | SHOW VARIABLES| | server_id | SHOW VARIABLES| | uncommitted_trx_duration_top_1 |information_schema.processlist and information_schema.innodb_trx| | uncommitted_trx_duration_top_2 |information_schema.processlist and information_schema.innodb_trx| diff --git a/actiontech_mysql_monitor.go b/actiontech_mysql_monitor.go index 81c60aa..96c13ed 100644 --- a/actiontech_mysql_monitor.go +++ b/actiontech_mysql_monitor.go @@ -63,7 +63,7 @@ var ( procs = flag.Bool("procs", true, "Whether to check SHOW PROCESSLIST") getQrtPercona = flag.Bool("get_qrt_percona", true, "Whether to get response times from Percona Server or MariaDB") getQrtMysql = flag.Bool("get_qrt_mysql", false, "Whether to get response times from MySQL (default: false)") - getUcTrxDurMysql = flag.Bool("get_uctrx_dur_mysql", true, "Whether to get uncommitted transaction duration from MySQL (default: false)") + getUcTrxDurMysql = flag.Bool("get_uctrx_dur_mysql", true, "Whether to get uncommitted transaction duration from MySQL (default: true)") discoveryPort = flag.Bool("discovery_port", false, "`discovery mysqld port`, print in json format (default: false)") useSudo = flag.Bool("sudo", true, "Use `sudo netstat...`") version = flag.Bool("version", false, "print version") @@ -174,7 +174,7 @@ func collect() ([]bool, []map[string]string) { // Collecting ... collectionInfo := make([]map[string]string, 9) - collectionExist := []bool{true, true, false, false, false, false, false, false, true} + collectionExist := []bool{true, true, false, false, false, false, false, false, false} collectionInfo[SHOW_STATUS] = collectAllRowsToMap("variable_name", "value", db, "SHOW /*!50002 GLOBAL */ STATUS") collectionInfo[SHOW_VARIABLES] = collectAllRowsToMap("variable_name", "value", db, "SHOW VARIABLES") @@ -244,7 +244,7 @@ func collect() ([]bool, []map[string]string) { []string{"state"}, db, "SHOW PROCESSLIST") timeCollection := collectMultiColumnAllRowsAsMapValue([]string{SHOW_PROCESSLIST_TIME_PRE}, - []string{"time"}, db, "SELECT time FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state NOT IN ('','sleep') AND user NOT IN ('root','repl') AND db != 'NULL'") + []string{"time"}, db, "SELECT time FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state NOT IN ('','sleep') AND user != 'root' AND db != 'NULL'") stringMapAdd(collectionInfo[SHOW_PROCESSLIST], stateCollection) stringMapAdd(collectionInfo[SHOW_PROCESSLIST], timeCollection)