3. 慢查询监控与定位:MySQL慢查询日志、pt-query-digest、Performance Schema
慢查询是数据库性能劣化的核心诱因之一。在实施熔断降级与连接池调优之前,必须建立一套精准、低延迟的慢查询监控体系。本章聚焦三种主流定位手段:MySQL 慢查询日志、pt-query-digest 与 Performance Schema,并给出生产环境下的组合策略。
3.1 MySQL 慢查询日志:基础配置与陷阱
慢查询日志是 MySQL 官方提供的最基础的慢 SQL 记录机制,默认关闭,需显式开启。
3.1.1 核心参数
| 参数名 | 默认值 | 推荐生产值 | 说明 |
|---|---|---|---|
slow_query_log |
OFF | ON | 开启慢查询日志 |
slow_query_log_file |
主机名-slow.log | /var/log/mysql/slow-query.log | 日志文件路径,建议独立磁盘 |
long_query_time |
10.000000 | 1.000000 或 0.500000 | 超过此阈值的 SQL 被记录(秒) |
log_queries_not_using_indexes |
OFF | ON | 记录未使用索引的查询(即使很快) |
log_slow_admin_statements |
OFF | ON | 记录 ALTER/ANALYZE 等管理语句 |
min_examined_row_limit |
0 | 1000 | 扫描行数超过此值才记录,过滤小查询 |
生产陷阱:切勿在生产库将
long_query_time 设为 0 或极低值(如 0.01),这会导致日志文件每秒写入数千条记录,引发磁盘 IO 风暴,甚至拖垮主库。建议从 1 秒起步,逐步下调。
3.1.2 动态配置示例
-- 在线开启慢查询日志(无需重启)
SET GLOBAL slow_query_log = ON;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = ON;
SET GLOBAL log_slow_admin_statements = ON;
SET GLOBAL min_examined_row_limit = 1000;
-- 验证配置
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';
3.2 pt-query-digest:慢日志分析利器
原生慢查询日志是纯文本,难以直接阅读。Percona Toolkit 中的 pt-query-digest 是业界标准分析工具,能将原始日志聚合为可读的报告。
3.2.1 典型用法
# 分析慢查询日志文件,输出到终端
pt-query-digest /var/log/mysql/slow-query.log
# 分析最近 1 小时的慢查询,输出到 HTML 报告
pt-query-digest --since '1 hour ago' /var/log/mysql/slow-query.log > report.html
# 从 MySQL 进程列表直接抓取分析(实时)
pt-query-digest --processlist h=localhost,u=root,p=your_password
# 分析 tcpdump 抓取的 MySQL 流量包
tcpdump -s 65535 -x -nn -q -tttt -i any port 3306 -c 100000 > mysql.tcp
pt-query-digest --type tcpdump mysql.tcp
3.2.2 输出解读要点
| 指标 | 含义 | 关注阈值 |
|---|---|---|
| Query_time: avg | 该指纹 SQL 的平均执行时间 | > 500ms 需关注 |
| Lock_time: avg | 平均锁等待时间 | > 200ms 可能锁冲突 |
| Rows_sent: avg | 平均返回行数 | > 1000 考虑分页 |
| Rows_examined: avg | 平均扫描行数 | > 10000 索引效率低 |
| Response time ratio | 该 SQL 占总响应时间的百分比 | > 10% 为 Top SQL |
最佳实践:将 pt-query-digest 配置为 crontab 定时任务,每 5 分钟分析一次慢日志,将 Top 5 SQL 推送到告警系统。结合连接池监控,当某条 SQL 的响应时间占比突增时,自动触发熔断阈值调整。
3.3 Performance Schema:细粒度监控引擎
Performance Schema(P_S)是 MySQL 5.6+ 内置的性能监控引擎,以 instrumentation 方式采集数据库内部事件,精度达到微秒级,且对性能影响极小(通常 < 5%)。
3.3.1 关键表与查询
| 表名 | 用途 | 核心字段 |
|---|---|---|
events_statements_summary_by_digest |
按 SQL 指纹聚合的统计 | DIGEST, SUM_TIMER_WAIT, COUNT_STAR, AVG_TIMER_WAIT |
events_statements_current |
当前正在执行的语句 | THREAD_ID, EVENT_NAME, SQL_TEXT, TIMER_START |
file_summary_by_instance |
文件 IO 等待统计 | FILE_NAME, COUNT_STAR, SUM_TIMER_WAIT |
table_io_waits_summary_by_table |
表级 IO 等待 | OBJECT_SCHEMA, OBJECT_NAME, COUNT_STAR |
3.3.2 实时慢查询定位 SQL
-- 查询当前正在执行且超过 2 秒的慢查询
SELECT
THREAD_ID,
EVENT_NAME,
SQL_TEXT,
ROUND(TIMER_WAIT / 1000000000, 2) AS wait_sec,
ROWS_EXAMINED,
ROWS_SENT
FROM performance_schema.events_statements_current
WHERE TIMER_WAIT > 2000000000 -- 2秒 = 2e9 皮秒
AND SQL_TEXT IS NOT NULL
ORDER BY wait_sec DESC
LIMIT 10;
-- 查询过去 5 分钟内最慢的 10 条 SQL 指纹
SELECT
DIGEST,
DIGEST_TEXT,
COUNT_STAR AS exec_count,
ROUND(SUM_TIMER_WAIT / 1000000000, 2) AS total_sec,
ROUND(AVG_TIMER_WAIT / 1000000000, 4) AS avg_sec,
ROUND(MAX_TIMER_WAIT / 1000000000, 2) AS max_sec,
SUM_ROWS_EXAMINED,
SUM_ROWS_SENT
FROM performance_schema.events_statements_summary_by_digest
WHERE SUM_TIMER_WAIT > 0
AND LAST_SEEN > NOW() - INTERVAL 5 MINUTE
ORDER BY total_sec DESC
LIMIT 10;
3.4 三种手段对比与组合策略
| 维度 | 慢查询日志 | pt-query-digest | Performance Schema |
|---|---|---|---|
| 数据来源 | 文件 | 日志文件 / tcpdump / processlist | 内存 instrumentation |
| 实时性 | 分钟级延迟(刷盘) | 近实时(processlist 模式) | 微秒级实时 |
| 性能开销 | 低(IO 写入) | 低(分析时消耗 CPU) | 极低(内存采样) |
| 历史回溯 | 依赖日志轮转策略 | 依赖日志文件保留 | 受 P_S 内存大小限制 |
| SQL 指纹聚合 | 需外部工具 | 内置聚合 | 内置 digest 聚合 |
| 适用场景 | 离线分析、审计 | 日常巡检、报告生成 | 实时告警、熔断触发 |
推荐组合:Performance Schema 作为实时监控与熔断触发的第一道防线;慢查询日志作为持久化审计的第二道防线;pt-query-digest 作为定期分析与容量规划的第三道防线。三者互补,覆盖从微秒级到天级的监控粒度。
3.5 生产环境监控配置清单
- 开启 Performance Schema:确认
performance_schema=ON,设置performance_schema_consumer_events_statements_history_long=ON。 - 配置慢查询日志:
long_query_time=1,log_queries_not_using_indexes=ON,日志文件独立磁盘。 - 部署 pt-query-digest 定时任务:每 5 分钟分析一次,输出 Top 10 到监控系统。
- 建立 P_S 实时告警:对
events_statements_current中执行超过 3 秒的 SQL 触发告警。 - 连接熔断联动:当某 SQL 指纹的 avg_sec 超过 2 秒且执行频率 > 100 次/分钟,自动降低该连接池的最大连接数或触发熔断。
关键指标:监控系统应重点关注 P95 响应时间 而非平均值。平均值会掩盖少量极慢查询对整体的影响。当 P95 响应时间超过 1 秒时,应立即启动慢查询定位流程。