Skip to content

Commit

Permalink
Add per user metrics to mysql input (#6132)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexKapustin authored Dec 15, 2020
1 parent ca7e3ff commit 21253ec
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
9 changes: 9 additions & 0 deletions plugins/inputs/mysql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ This plugin gathers the statistic data from MySQL server
# gather_file_events_stats = false

## gather metrics from PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_DIGEST
# gather_perf_events_statements = false
#
## gather metrics from PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME
# gather_perf_sum_per_acc_per_event = false
#
## list of events to be gathered for gather_perf_sum_per_acc_per_event
## in case of empty list all events will be gathered
# perf_summary_events = []
#
# gather_perf_events_statements = false

## the limits for metrics form perf_events_statements
Expand Down
185 changes: 185 additions & 0 deletions plugins/inputs/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type Mysql struct {
GatherFileEventsStats bool `toml:"gather_file_events_stats"`
GatherPerfEventsStatements bool `toml:"gather_perf_events_statements"`
GatherGlobalVars bool `toml:"gather_global_variables"`
GatherPerfSummaryPerAccountPerEvent bool `toml:"gather_perf_sum_per_acc_per_event"`
PerfSummaryEvents []string `toml:"perf_summary_events"`
IntervalSlow string `toml:"interval_slow"`
MetricVersion int `toml:"metric_version"`

Expand Down Expand Up @@ -121,6 +123,13 @@ const sampleConfig = `
# perf_events_statements_limit = 250
# perf_events_statements_time_limit = 86400
## gather metrics from PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME
# gather_perf_sum_per_acc_per_event = false
## list of events to be gathered for gather_perf_sum_per_acc_per_event
## in case of empty list all events will be gathered
# perf_summary_events = []
## Some queries we may want to run less often (such as SHOW GLOBAL VARIABLES)
## example: interval_slow = "30m"
# interval_slow = ""
Expand Down Expand Up @@ -416,6 +425,38 @@ const (
FROM information_schema.tables
WHERE table_schema = 'performance_schema' AND table_name = ?
`

perfSummaryPerAccountPerEvent = `
SELECT
coalesce(user, "unknown"),
coalesce(host, "unknown"),
coalesce(event_name, "unknown"),
count_star,
sum_timer_wait,
min_timer_wait,
avg_timer_wait,
max_timer_wait,
sum_lock_time,
sum_errors,
sum_warnings,
sum_rows_affected,
sum_rows_sent,
sum_rows_examined,
sum_created_tmp_disk_tables,
sum_created_tmp_tables,
sum_select_full_join,
sum_select_full_range_join,
sum_select_range,
sum_select_range_check,
sum_select_scan,
sum_sort_merge_passes,
sum_sort_range,
sum_sort_rows,
sum_sort_scan,
sum_no_index_used,
sum_no_good_index_used
FROM performance_schema.events_statements_summary_by_account_by_event_name
`
)

func (m *Mysql) gatherServer(serv string, acc telegraf.Accumulator) error {
Expand Down Expand Up @@ -491,6 +532,13 @@ func (m *Mysql) gatherServer(serv string, acc telegraf.Accumulator) error {
}
}

if m.GatherPerfSummaryPerAccountPerEvent {
err = m.gatherPerfSummaryPerAccountPerEvent(db, serv, acc)
if err != nil {
return err
}
}

if m.GatherTableIOWaits {
err = m.gatherPerfTableIOWaits(db, serv, acc)
if err != nil {
Expand Down Expand Up @@ -1262,6 +1310,143 @@ func (m *Mysql) gatherInnoDBMetrics(db *sql.DB, serv string, acc telegraf.Accumu
return nil
}

// gatherPerfSummaryPerAccountPerEvent can be used to fetch enabled metrics from
// performance_schema.events_statements_summary_by_account_by_event_name
func (m *Mysql) gatherPerfSummaryPerAccountPerEvent(db *sql.DB, serv string, acc telegraf.Accumulator) error {
sqlQuery := perfSummaryPerAccountPerEvent

var rows *sql.Rows
var err error

var (
srcUser string
srcHost string
eventName string
countStar float64
sumTimerWait float64
minTimerWait float64
avgTimerWait float64
maxTimerWait float64
sumLockTime float64
sumErrors float64
sumWarnings float64
sumRowsAffected float64
sumRowsSent float64
sumRowsExamined float64
sumCreatedTmpDiskTables float64
sumCreatedTmpTables float64
sumSelectFullJoin float64
sumSelectFullRangeJoin float64
sumSelectRange float64
sumSelectRangeCheck float64
sumSelectScan float64
sumSortMergePasses float64
sumSortRange float64
sumSortRows float64
sumSortScan float64
sumNoIndexUsed float64
sumNoGoodIndexUsed float64
)

var events []interface{}
// if we have perf_summary_events set - select only listed events (adding filter criteria for rows)
if len(m.PerfSummaryEvents) > 0 {
sqlQuery += " WHERE EVENT_NAME IN ("
for i, eventName := range m.PerfSummaryEvents {
if i > 0 {
sqlQuery += ", "
}
sqlQuery += "?"
events = append(events, eventName)
}
sqlQuery += ")"

rows, err = db.Query(sqlQuery, events...)
} else {
// otherwise no filter, hence, select all rows
rows, err = db.Query(perfSummaryPerAccountPerEvent)
}

if err != nil {
return err
}
defer rows.Close()

// parse DSN and save server tag
servtag := getDSNTag(serv)
tags := map[string]string{"server": servtag}
for rows.Next() {
if err := rows.Scan(
&srcUser,
&srcHost,
&eventName,
&countStar,
&sumTimerWait,
&minTimerWait,
&avgTimerWait,
&maxTimerWait,
&sumLockTime,
&sumErrors,
&sumWarnings,
&sumRowsAffected,
&sumRowsSent,
&sumRowsExamined,
&sumCreatedTmpDiskTables,
&sumCreatedTmpTables,
&sumSelectFullJoin,
&sumSelectFullRangeJoin,
&sumSelectRange,
&sumSelectRangeCheck,
&sumSelectScan,
&sumSortMergePasses,
&sumSortRange,
&sumSortRows,
&sumSortScan,
&sumNoIndexUsed,
&sumNoGoodIndexUsed,
); err != nil {
return err
}
srcUser = strings.ToLower(srcUser)
srcHost = strings.ToLower(srcHost)

sqlLWTags := copyTags(tags)
sqlLWTags["src_user"] = srcUser
sqlLWTags["src_host"] = srcHost
sqlLWTags["event"] = eventName
sqlLWFields := map[string]interface{}{
"count_star": countStar,
"sum_timer_wait": sumTimerWait,
"min_timer_wait": minTimerWait,
"avg_timer_wait": avgTimerWait,
"max_timer_wait": maxTimerWait,
"sum_lock_time": sumLockTime,
"sum_errors": sumErrors,
"sum_warnings": sumWarnings,
"sum_rows_affected": sumRowsAffected,
"sum_rows_sent": sumRowsSent,
"sum_rows_examined": sumRowsExamined,
"sum_created_tmp_disk_tables": sumCreatedTmpDiskTables,
"sum_created_tmp_tables": sumCreatedTmpTables,
"sum_select_full_join": sumSelectFullJoin,
"sum_select_full_range_join": sumSelectFullRangeJoin,
"sum_select_range": sumSelectRange,
"sum_select_range_check": sumSelectRangeCheck,
"sum_select_scan": sumSelectScan,
"sum_sort_merge_passes": sumSortMergePasses,
"sum_sort_range": sumSortRange,
"sum_sort_rows": sumSortRows,
"sum_sort_scan": sumSortScan,
"sum_no_index_used": sumNoIndexUsed,
"sum_no_good_index_used": sumNoGoodIndexUsed,
}
acc.AddFields("mysql_perf_acc_event", sqlLWFields, sqlLWTags)

}

return nil
}

// gatherPerfTableLockWaits can be used to get
// the total number and time for SQL and external lock wait events
// for each table and operation
Expand Down

0 comments on commit 21253ec

Please sign in to comment.