MySQL慢查询日志开启,pt‑query‑digest分析
数据库响应慢时,最先要看的就是慢查询日志。
MySQL慢查询日志会记录执行时间超过阈值的SQL语句,而pt-query-digest能将零散的慢日志汇总成可读报告,帮你快速找到最耗时的SQL。
本文面向刚接触数据库优化的用户,按步骤完成日志开启、工具安装、分析输出和结果验证,全程可直接照做。
准备:确认环境与慢日志现状
开始前先确认MySQL版本和当前慢日志状态。
登录MySQL后执行:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
如果 slow_query_log 为 OFF,需要手动开启。
开启前还要确认日志写到哪里:
SHOW VARIABLES LIKE 'slow_query_log_file';
建议把日志路径放在数据目录之外,避免磁盘占用影响数据库运行。pt-query-digest 是 Percona Toolkit 的一部分,需要单独安装,后续再讲。
开启慢查询日志并设置合理阈值
临时开启可用下面的SQL,也可以在配置文件 my.cnf 中永久修改。
临时开启(重启失效):
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
这里把 long_query_time 设为1秒,表示超过1秒的SQL都会被记录。
线上建议从1秒开始,避免记录过多无意义日志。
如果只是排查特定问题,可以先设为5秒再逐步调低。
永久开启则编辑 my.cnf,在 [mysqld] 段加入:
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log
log_queries_not_using_indexes = 1
log_queries_not_using_indexes 会额外记录未走索引的查询,对排查索引失效很有帮助。
修改后重启MySQL:
systemctl restart mysqld
验证是否生效:
SHOW VARIABLES LIKE 'slow_query_log';
值为 ON 即成功。
安装并运行 pt-query-digest
pt-query-digest 不随MySQL自带,需要安装 Percona Toolkit。
CentOS/RHEL 系统可用:
yum install -y percona-toolkit
Ubuntu/Debian 系统:
apt-get install -y percona-toolkit
如果官方源不可用,也可以前往 Percona 官网下载对应发行版的包。
安装完成后直接分析慢日志文件:
pt-query-digest /var/log/mysql/slow.log
执行后会在终端直接输出分析报告,包含每个SQL的响应时间占比、执行次数、平均耗时等。报告顶部会列出最耗时的SQL摘要,中间是具体语句和统计信息,末尾是详细指标。
更实用的做法是把结果保存到文件,方便反复查看:
pt-query-digest /var/log/mysql/slow.log > slow_report.txt
也可以分析连续多天日志,比如用 -since 指定时间范围:
pt-query-digest --since='2025-01-01 00:00:00' /var/log/mysql/slow.log
常见报错与避坑要点
权限不足:如果日志文件属主不是MySQL用户,pt-query-digest 会提示无法读取。
先确认日志路径有读权限,或使用 sudo 执行。
日志文件过大:慢日志积累过久会占用大量磁盘,建议开启日志轮转。
Linux 下可以用 logrotate 管理,比如每天切割并保留30天,避免日志无限增长。
临时SET不生效:MySQL 8.0 中部分参数是只读的,修改 slow_query_log 也要注意是全局变量。
如果改完还是 OFF,检查 my.cnf 里是否被其他配置覆盖,并确认启动时没有报错。
pt-query-digest 不识别日志:如果之前设置过 log_output = TABLE,慢日志会写入 mysql.slow_log 表而不是文件。
此时要用SQL查询表,或者先把 log_output 改回 FILE。
如何验证分析结果是否有效
运行 pt-query-digest 后,重点看报告顶部的 Profile 排行。
如果某条SQL的响应时间占比超过50%,说明它大概率是瓶颈。
可执行 EXPLAIN 查看该语句的执行计划:
EXPLAIN SELECT * FROM orders WHERE user_id = 123;
如果 type 为 ALL 或未命中索引,就针对该查询添加合适的索引。
例如:
ALTER TABLE orders ADD INDEX idx_user_id (user_id);
再重新执行慢查询语句,确认耗时明显下降。
最后再次运行 pt-query-digest,观察同类SQL是否从Top列表消失。
建议在测试环境先演练一遍,再对生产库做变更。
遇到异常时,优先回看本文的避坑部分,尤其是日志路径、权限和日志表模式的差异。
只要慢查询日志能正常生成,pt-query-digest 就能准确反映数据库的SQL健康度。