慢查询日志需开启并合理配置:确认slow_query_log=on,long_query_time设为0.1~0.5秒,启用log_queries_not_using_indexes;日志路径应独立分区;用mysqldumpslow或pt-query-digest分析,结合performance_schema实时验证sql频次与消耗。

确认慢查询日志是否开启且配置合理
MySQL 慢查询日志不是默认开启的,CPU 飙升时如果日志没开,就完全没法回溯。先检查 slow_query_log 是否为 ON,再看 long_query_time 设置是否过松——比如设成 10 秒,那执行 2 秒就卡住 CPU 的 SQL 根本不会记录。
- 用
SHOW VARIABLES LIKE 'slow_query_log%';查开关和日志路径 -
long_query_time建议调到0.1或0.5(支持小数),尤其在高并发 OLTP 场景下 - 务必开启
log_queries_not_using_indexes,避免漏掉“快但伤 CPU”的全表扫描语句 - 日志文件路径建议指向独立磁盘分区,避免和数据目录争 I/O,否则日志写入本身可能加剧 CPU/IO 压力
用 mysqldumpslow 快速筛出高频高耗时 SQL
直接打开 slow.log 看原始内容效率极低,重复 SQL 多、参数占位混乱、无聚合统计。mysqldumpslow 是 MySQL 自带的解析工具,能按次数、时间、锁等待等维度归并排序。
- 查最耗时的前 5 条:
mysqldumpslow -s t -t 5 /var/lib/mysql/slow.log - 查访问行数最多的(常对应全表扫描):
mysqldumpslow -s al -t 5 /var/lib/mysql/slow.log - 加
-g过滤关键词,比如只看含UPDATE的:mysqldumpslow -g "UPDATE" /var/lib/mysql/slow.log - 注意:如果 SQL 中有大量不同 ID(如
WHERE id = 123),默认会被当成不同语句;加-a参数可禁用数字替换,但更推荐用pt-query-digest替代(见下一条)
用 pt-query-digest 深度分析并定位真实瓶颈
mysqldumpslow 简单但粗糙,pt-query-digest(Percona Toolkit)才能真正关联执行计划、索引缺失、临时表/文件排序等关键线索。它输出里 “Query_time” 和 “Lock_time” 接近,说明是锁竞争;“Rows_examined” 远大于 “Rows_sent”,大概率缺索引或条件失效。
- 基础分析命令:
pt-query-digest /var/lib/mysql/slow.log --limit 10 - 重点看输出中的
EXPLAIN建议列(如果有--explain参数),它会自动对典型 SQL 执行EXPLAIN并标出type=ALL、Extra=Using filesort等风险项 - 加
--filter '$event->{Bytes} > 10000'可过滤大结果集查询(易引发网络和 CPU 开销) - 若日志量大,先用
grep截取故障时间段:sed -n '/# Time: 2024-06-10T14:20:00/,/# Time: 2024-06-10T14:30:00/p' slow.log | pt-query-digest
验证 SQL 问题是否真导致 CPU 飙升,而非误判
慢日志里排第一的 SQL 不一定就是 CPU 元凶。比如某条 SQL 执行 5 秒但只跑 1 次,而另一条 0.3 秒的 SQL 每秒执行 200 次,后者更容易打满 CPU 核心。必须结合 performance_schema 实时反查。
- 查当前活跃高消耗线程:
SELECT THREAD_ID, PROCESSLIST_INFO, PROCESSLIST_TIME FROM performance_schema.threads t JOIN performance_schema.events_statements_current e USING (THREAD_ID) WHERE e.TIMER_WAIT > 100000000000 ORDER BY e.TIMER_WAIT DESC LIMIT 5; - 查历史 Top SQL(需提前开启
events_statements_history_long):SELECT DIGEST_TEXT, COUNT_STAR, SUM_TIMER_WAIT, SUM_ROWS_EXAMINED FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 5; - 注意:某些 SQL 在慢日志里不显眼,但在
SHOW PROCESSLIST中长期处于Sending data或Copying to tmp table状态,这类才是真正的 CPU/内存杀手
慢日志只是线索入口,真正锁定问题 SQL 得交叉比对执行频次、执行计划、实时状态三者。单独依赖任一维度都容易绕远路。











