MySQL性能监控的核心是持续采集关键运行指标,并从中识别异常。无论是生产环境突发CPU飙高,还是业务高峰期响应明显变慢,如果没有一套有效的监控体系,运维和开发人员就只能凭感觉猜测原因。完整的监控应该覆盖实例级别的吞吐量、连接状态、InnoDB引擎内部活动、SQL执行效率以及资源使用情况,这样才能既看到全局趋势,又能下钻到具体语句。

很多团队只开启了慢查询日志,把监控等同于记录慢SQL。实际上,慢查询只能反映已经发生的执行耗时,无法体现连接堆积、锁争用、缓冲池抖动或临时表膨胀等问题。本章先梳理指标框架,后续再介绍具体工具配置和使用方法。
构建MySQL性能监控指标体系
监控MySQL性能,首先要定义清楚该看什么。核心指标可以分为几个维度:吞吐量、连接与线程、InnoDB缓冲池、锁与等待、临时表与排序、复制状态(如果是主从架构)。吞吐量通常用QPS(每秒查询数)和TPS(每秒事务数)衡量,它们可以从Questions和Com_commit、Com_rollback等状态变量的增量计算出来。连接与线程方面,Threads_connected表示当前连接数,Threads_running表示正在执行语句的线程数,如果后者长期接近或超过CPU核数,通常说明有并发堆积。
InnoDB缓冲池命中率是另一个关键指标。它反映数据页在内存中被直接命中的比例,计算公式为:1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests)。命中率低于99%并不一定代表有问题,但如果出现明显下降且磁盘读次数持续上升,就需要检查是否有大量冷数据被频繁访问,或者缓冲池设置过小。此外还要关注Innodb_row_lock_waits和Innodb_row_lock_time,这两个变量能揭示行锁等待的总次数和总耗时,是判断锁争用严重程度的直接依据。
临时表与排序也经常被忽略。当SQL需要对结果做分组或排序,且无法利用索引时,MySQL会创建内部临时表或执行文件排序。可以通过Created_tmp_disk_tables和Created_tmp_tables的比值判断有多少临时表落到了磁盘上。如果磁盘临时表比例过高,通常意味着关联查询或分组字段缺少合适索引。将这些指标纳入监控后,再配合具体SQL分析工具,就能形成完整的观察链路。
使用内置工具采集性能数据
MySQL自带了两种主要的性能数据来源:SHOW STATUS命令和Performance Schema。前者提供实例级别的累计状态计数器,适合做差值计算和趋势监控;后者提供更细粒度的事件等待、SQL语句执行统计、内存使用等数据,适合深入分析具体问题。先看SHOW GLOBAL STATUS的使用,下面的SQL可以获取连接和InnoDB相关指标:
SHOW GLOBAL STATUS WHERE Variable_name IN (
'Threads_connected',
'Threads_running',
'Innodb_buffer_pool_read_requests',
'Innodb_buffer_pool_reads',
'Innodb_row_lock_waits',
'Innodb_row_lock_time',
'Created_tmp_disk_tables',
'Created_tmp_tables'
);这些计数器是自实例启动以来的累计值,因此监控系统需要周期性地采集并计算增量,例如每秒或每分钟的差值。单次查询得到的绝对值意义有限,持续观察差值才能发现异常波动。如果某个时段Innodb_row_lock_waits的增量突然变大,同时Innodb_row_lock_time也同步上升,就可以基本判定出现了锁等待问题。
Performance Schema则提供了更结构化的视角。它默认可能处于开启状态,可以通过SHOW VARIABLES LIKE 'performance_schema';确认。借助Performance Schema的events_statements_summary_by_digest表,可以统计执行次数最多、总耗时最长的SQL摘要,这是定位慢查询的重要途径。下面查询按总耗时排序的前5条SQL摘要:
SELECT DIGEST_TEXT,
COUNT_STAR AS exec_count,
SUM_TIMER_WAIT / 1000000000000 AS total_sec,
AVG_TIMER_WAIT / 1000000000 AS avg_ms
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 5;Performance Schema的优点是无需额外安装,且能采集SQL语句、等待事件、文件I/O、表锁等大量细节。缺点是开启所有监控项会带来一定性能开销,并且历史数据默认不持久化,需要配合外部采集器保存。相比SHOW STATUS,Performance Schema更适合在出现问题时做深度排查,而不是替代所有基础指标监控。
常用外部监控工具与慢查询分析
仅靠内置命令很难满足生产环境的可视化、告警和长期存储需求,因此通常需要引入外部工具。目前使用最广泛的开源组合是mysqld_exporter、Prometheus和Grafana。mysqld_exporter通过连接MySQL执行SHOW STATUS、SHOW VARIABLES和Performance Schema查询,将结果转换成Prometheus可以抓取的指标。下面是一个简单的mysqld_exporter配置示例,将数据库账号信息写入配置文件:
export DATA_SOURCE_NAME="exporter:password@tcp(127.0.0.1:3306)/" ./mysqld_exporter --config.my-cnf=/etc/mysqld_exporter/.my.cnf
Prometheus负责按固定周期抓取mysqld_exporter暴露的指标,并存储为时间序列数据;Grafana则通过预设或自定义仪表盘展示曲线。很多团队会使用开源的MySQL Overview仪表盘,直接查看QPS、连接数、缓冲池命中率、InnoDB读写、复制延迟等关键图表。设置告警规则时,建议对Threads_running超过阈值、缓冲池命中率明显下降、慢查询数量激增等情况触发通知,避免只在故障发生后才发现。
对于慢查询分析,Percona Toolkit中的pt-query-digest是非常实用的工具。它可以直接解析MySQL慢查询日志、通用日志或Performance Schema数据,输出按查询耗时、执行次数等维度聚合的报告。使用方式如下:
pt-query-digest /var/log/mysql/mysql-slow.log --order-by=Query_time:sum --limit=10
该命令会生成一份报告,列出耗时最长的SQL以及它们的执行次数、平均耗时、锁等待时间等。报告中还会给出每条SQL的样例和统计信息,帮助开发者快速识别重复执行且开销巨大的语句。虽然pt-query-digest不支持实时图表,但作为阶段性的慢日志回顾和优化优先级排序工具,它非常高效。
从监控到优化的完整工作流
监控数据只有转化为行动才有价值。一个可复用的性能优化工作流通常包含以下步骤:发现异常、采集现场数据、定位瓶颈、实施优化、验证效果并纳入持续监控。当Grafana告警提示Threads_running持续偏高时,先查看当前连接列表和正在执行的SQL:
SHOW FULL PROCESSLIST;
如果发现多条SQL处于Sending data或Statistics状态,说明它们可能在扫描大量数据。接下来从Performance Schema的events_statements_current或慢查询日志中提取具体语句,使用EXPLAIN分析执行计划。例如发现某个查询没有使用索引,而是做了全表扫描,优化方向就很明确:为过滤条件或关联字段建立复合索引。验证优化效果时,可以再次观察Threads_running是否回落,以及该SQL的执行耗时是否缩短。
另一个常见场景是缓冲池命中率突然下降。通过对比监控曲线,往往能发现某个时间点有大批量导入或全表扫描任务在运行,大量冷数据将热数据挤出缓冲池。此时除了优化任务本身的查询方式,还可以考虑适当增大innodb_buffer_pool_size,或者将批处理任务安排在业务低峰执行。锁等待问题则需要结合Innodb_row_lock_waits增量、Performance Schema中的data_lock_waits表以及SHOW ENGINE INNODB STATUS输出,找出持锁事务和被阻塞事务,再决定是调整事务顺序、缩短事务时长还是修改隔离级别。
最后,监控体系本身也需要定期复盘。随着业务增长和表结构变化,原先设置的阈值可能不再适用。每隔一段时间检查告警是否过于频繁或过于迟钝,补充新上线的业务表性能基线,并把优化后的SQL纳入慢查询白名单或基线对比,才能让MySQL监控从被动救火转向主动预防。