MySQL监控与性能指标
MySQL 是业务系统中最常见的数据库,但用好它并不容易。索引设计、SQL 优化、事务处理都是日常开发中需要关注的点。本文从实际场景出发,讲常见问题和解决思路。
一、监控维度
#
1.1 四个黄金指标
| 维度 |
指标 |
说明 |
| 吞吐量 |
QPS/TPS |
每秒查询/事务数 |
| 延迟 |
查询响应时间 |
SQL执行耗时 |
| 错误 |
慢查询/错误率 |
性能问题和异常 |
| 饱和度 |
连接数/CPU/IO |
资源使用程度 |
#
1.2 监控层次
┌─────────────────────────────────────┐ │ 业务层:慢查询、错误率、响应时间 │ ├─────────────────────────────────────┤ │ 实例层:QPS、连接数、复制状态 │ ├─────────────────────────────────────┤ │ 存储层:磁盘IO、Buffer Pool命中率 │ ├─────────────────────────────────────┤ │ 系统层:CPU、内存、网络、磁盘 │ └─────────────────────────────────────┘
|
二、核心性能指标
#
2.1 吞吐量指标
SHOW GLOBAL STATUS LIKE 'Queries';
SHOW GLOBAL STATUS LIKE 'Com_commit'; SHOW GLOBAL STATUS LIKE 'Com_rollback';
SHOW GLOBAL STATUS LIKE 'Com_%';
|
#
2.2 连接指标
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW GLOBAL STATUS LIKE 'Connections';
|
#
2.3 查询缓存指标(MySQL 8.0已移除)
SHOW GLOBAL STATUS LIKE 'Qcache%';
|
#
2.4 InnoDB指标
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests'; SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';
SHOW GLOBAL STATUS LIKE 'Innodb_rows_%';
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock_waits'; SHOW GLOBAL STATUS LIKE 'Innodb_row_lock_time_avg';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_%';
SHOW GLOBAL STATUS LIKE 'Innodb_log_waits'; SHOW GLOBAL STATUS LIKE 'Innodb_os_log_fsyncs';
|
#
2.5 复制指标
SHOW SLAVE STATUS \G;
SHOW MASTER STATUS;
|
#
2.6 慢查询指标
SHOW GLOBAL STATUS LIKE 'Slow_queries';
SHOW GLOBAL STATUS LIKE 'Select_scan'; SHOW GLOBAL STATUS LIKE 'Select_full_join';
SHOW GLOBAL STATUS LIKE 'Created_tmp_%';
|
#
3.1 开启配置
[mysqld] performance_schema = ON
|
#
3.2 常用查询
SELECT DIGEST_TEXT AS query, COUNT_STAR AS exec_count, AVG_TIMER_WAIT / 1000000000000 AS avg_time_sec, MAX_TIMER_WAIT / 1000000000000 AS max_time_sec, SUM_ROWS_SENT AS total_rows_sent, SUM_ROWS_EXAMINED AS total_rows_examined FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
SELECT OBJECT_SCHEMA, OBJECT_NAME, COUNT_READ, COUNT_WRITE, SUM_NUMBER_OF_BYTES_READ, SUM_NUMBER_OF_BYTES_WRITE FROM performance_schema.table_io_waits_summary_by_table ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
SELECT OBJECT_SCHEMA, OBJECT_NAME, COUNT_READ, COUNT_WRITE, SUM_TIMER_WAIT FROM performance_schema.table_lock_waits_summary_by_table ORDER BY SUM_TIMER_WAIT DESC;
SELECT EVENT_NAME, COUNT_READ, COUNT_WRITE, SUM_NUMBER_OF_BYTES_READ, SUM_NUMBER_OF_BYTES_WRITE FROM performance_schema.file_summary_by_event_name WHERE EVENT_NAME LIKE '%innodb%' ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
|
#
3.3 线程监控
SELECT THREAD_ID, NAME, PROCESSLIST_ID, PROCESSLIST_USER, PROCESSLIST_HOST, PROCESSLIST_DB, PROCESSLIST_COMMAND, PROCESSLIST_STATE, PROCESSLIST_TIME, PROCESSLIST_INFO FROM performance_schema.threads WHERE TYPE = 'FOREGROUND' ORDER BY PROCESSLIST_TIME DESC;
|
四、sys系统库
MySQL 5.7+ 提供的便捷视图:
SELECT * FROM sys.statements_with_full_table_scans;
SELECT * FROM sys.statements_with_runtimes_in_95th_percentile;
SELECT * FROM sys.io_global_by_file_by_bytes;
SELECT * FROM sys.statements_with_temp_tables;
SELECT * FROM sys.statements_with_full_table_scans;
SELECT * FROM sys.innodb_lock_waits;
SELECT * FROM sys.host_summary;
|
五、Prometheus + Grafana监控
#
5.1 mysqld_exporter
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.0/mysqld_exporter-0.15.0.linux-amd64.tar.gz tar xzf mysqld_exporter-*.tar.gz
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'password'; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
cat > ~/.my.cnf <<EOF [client] user=exporter password=password EOF
./mysqld_exporter --config.my-cnf=~/.my.cnf
|
#
5.2 Prometheus配置
scrape_configs: - job_name: 'mysql' static_configs: - targets: ['localhost:9104'] labels: instance: 'mysql-prod-01'
|
#
5.3 Grafana仪表盘
导入MySQL监控Dashboard(ID: 7362 或 11323):
核心面板:
- MySQL Uptime
- Current QPS
- Connections
- Active Threads
- Slow Queries
- Replication Lag
- Buffer Pool Hit Ratio
#
5.4 告警规则
groups: - name: mysql rules: - alert: MySQLDown expr: mysql_up == 0 for: 1m labels: severity: critical annotations: summary: "MySQL实例宕机" - alert: MySQLHighConnections expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections > 0.8 for: 5m labels: severity: warning annotations: summary: "MySQL连接数超过80%" - alert: MySQLSlowQueries expr: rate(mysql_global_status_slow_queries[5m]) > 1 for: 5m labels: severity: warning annotations: summary: "MySQL慢查询增长" - alert: MySQLReplicationLag expr: mysql_slave_lag_seconds > 10 for: 5m labels: severity: warning annotations: summary: "MySQL复制延迟超过10秒" - alert: MySQLBufferPoolHitRatio expr: rate(mysql_global_status_innodb_buffer_pool_reads[5m]) / rate(mysql_global_status_innodb_buffer_pool_read_requests[5m]) > 0.01 for: 10m labels: severity: warning annotations: summary: "Buffer Pool命中率低于99%"
|
六、慢查询监控
#
6.1 实时慢查询分析
SELECT THREAD_ID, PROCESSLIST_ID, PROCESSLIST_USER, PROCESSLIST_HOST, PROCESSLIST_DB, PROCESSLIST_TIME, PROCESSLIST_INFO FROM performance_schema.threads WHERE PROCESSLIST_COMMAND = 'Query' AND PROCESSLIST_TIME > 10 ORDER BY PROCESSLIST_TIME DESC;
|
#
6.2 pt-kill自动杀慢查询
pt-kill --host=localhost --user=root --password=password \ --match-command='Query' \ --match-state='Sending data|Copying to tmp table' \ --busy-time=60 \ --victims=all \ --interval=10 \ --kill \ --print
|
七、容量规划
#
7.1 数据增长趋势
SELECT table_schema, ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS size_gb FROM information_schema.tables GROUP BY table_schema ORDER BY size_gb DESC;
SELECT table_name, ROUND(data_length / 1024 / 1024, 2) AS data_mb, ROUND(index_length / 1024 / 1024, 2) AS index_mb, table_rows FROM information_schema.tables WHERE table_schema = 'mydb' ORDER BY (data_length + index_length) DESC LIMIT 20;
|
#
7.2 QPS增长趋势
使用Prometheus查询:
# QPS趋势 rate(mysql_global_status_queries[1m])
# 连接数趋势 mysql_global_status_threads_connected
# 磁盘使用趋势 mysql_global_status_innodb_data_written
|
八、监控检查清单
#
8.1 每日检查
#
8.2 每周检查
#
8.3 每月检查
九、总结
| 指标类别 |
关键指标 |
告警阈值 |
| 可用性 |
mysql_up |
= 0 |
| 连接 |
Threads_connected/max_connections |
> 80% |
| 复制 |
Seconds_Behind_Master |
> 10秒 |
| 查询 |
Slow_queries增长率 |
突增 |
| 缓冲 |
Buffer Pool命中率 |
< 95% |
| 锁 |
Innodb_row_lock_waits |
持续增加 |
| 磁盘 |
磁盘使用率 |
> 80% |
监控的核心价值:
- 及时发现问题,缩短故障时间
- 掌握性能趋势,提前容量规划
- 量化优化效果,指导调优方向
- 提供数据支撑,辅助决策判断
核心要点
索引设计的原则:最左前缀原则、避免索引列参与计算、选择合适的索引类型
SQL 优化的方法:使用 EXPLAIN 分析执行计划、避免 SELECT *、优化 JOIN
事务隔离级别的选择:根据业务需求选择合适的级别
常见的锁问题:行锁、表锁、死锁的处理
总结
MySQL 优化是一个持续的过程,需要结合业务特点和数据量来调整。在实际项目中,定期分析慢查询日志、优化索引、调整配置参数,都能提升数据库性能。