确认 slow_query_log 当前是否为 on:执行 show variables like 'slow_query_log',返回 on 才算真正启用,off 则未生效,即使配置文件已设置也无效。

确认 slow_query_log 当前是否为 ON
很多线上问题卡在「以为开了,其实没开」。直接查变量比翻配置文件快,而且运行时状态才决定日志是否真在写:SHOW VARIABLES LIKE 'slow_query_log' 返回 ON 才算启用。如果值是 OFF,哪怕 my.cnf 里写了 slow_query_log = ON,也白搭——必须重启或执行 SET GLOBAL slow_query_log = 'ON'。
设置合理的 long_query_time 阈值
默认 10 秒太宽松,线上基本捕不到真实慢查询;设成 0 又会记录所有语句(包括 SELECT 1),IO 压力陡增。关键看业务响应水位:
- Web 接口平均耗时 200ms,建议从
0.5开始试(单位秒,支持小数) - 高并发核心服务可放宽到
1.0或2.0,避免日志刷爆磁盘 -
SET GLOBAL long_query_time = 0.5后,只对新连接生效,已存在的连接仍用旧值
指定可写的 slow_query_log_file 路径
slow_query_log_file 告诉 MySQL 日志写到哪,但路径必须满足两个硬条件:
- 目录存在,且 MySQL 进程用户(如
mysql)有写权限:ls -ld /var/log/mysql看权限,必要时sudo chown mysql:mysql /var/log/mysql - SELinux 启用的系统(如 CentOS)可能拦截写操作:
setsebool -P mysqld_can_network_connect_db 1和setsebool -P mysqld_disable_trans 1可能需要 - 某些 MySQL 版本(如 5.7)把
slow_query_log_file设为只读变量,此时只能靠配置文件修改,SET GLOBAL会报错
log_output 选 FILE 还是 TABLE?
log_output 决定日志落地方式,不是纯偏好问题,而是权衡排查效率和资源消耗:
-
log_output = 'FILE':写入文件,适合长期归档,用mysqldumpslow或pt-query-digest分析 -
log_output = 'TABLE':写入mysql.slow_log表,可直接SELECT查询,适合临时开、快速捞最近慢查;但该表是 CSV 引擎,无索引,数据量一大就卡 - 两者可并用:
log_output = 'FILE,TABLE',但注意磁盘和表空间双倍消耗,生产慎选 -
log_output必须用SET GLOBAL生效,改配置文件不热加载
最容易被忽略的是 min_examined_row_limit 和 log_queries_not_using_indexes:前者默认为 0,但如果设成 1000,那扫描行数不足的查询即使超时也不会记;后者一开可能让日志量暴增 10–100 倍,尤其当业务里大量小查询没走索引时——上线前务必关掉或先在从库试跑。











