执行 show variables like 'slow_query_log' 查看是否为 on 才算启用;slow_query_log_file 指明日志路径且 mysql 进程需有写权限;long_query_time 建议按业务响应水位设为 0.5 秒起;log_output 支持 file、table 或两者并用,但需 set global 生效;开启后无日志需检查 min_examined_row_limit 等阈值。

如何确认 slow_query_log 当前是否开启
直接查变量比翻配置文件快,而且运行时状态才决定日志是否真在写:
- 执行
SHOW VARIABLES LIKE 'slow_query_log',返回ON才算启用 - 如果值是
OFF,改了my.cnf也没用,必须重启或用SET GLOBAL slow_query_log = ON -
slow_query_log_file变量告诉你日志写到哪,注意路径 MySQL 进程得有写权限,常见坑是写进/var/log/mysql/却没给mysql用户权限
设置 long_query_time 到多少才算合理
默认 10 秒太宽松,线上基本没用;设太低又容易刷爆磁盘。关键看你的业务响应水位:
- Web 接口平均耗时 200ms,建议从
0.5开始试(单位秒,支持小数) - 执行
SET GLOBAL long_query_time = 0.5后,新连接生效,老连接仍用旧值 - 注意:MySQL 5.6+ 对
long_query_time的 SET GLOBAL 是会话级的,但只影响后续查询,已执行中的不中断 - 别设
0—— 那会记录所有查询,包括SELECT 1这种,IO 压力陡增
log_output 决定日志往哪写,FILE 和 TABLE 怎么选
默认 FILE,但有些场景 TABLE 更方便排查:
-
log_output = 'FILE':日志写进文件,用mysqldumpslow或pt-query-digest分析,适合长期归档 -
log_output = 'TABLE':写进mysql.slow_log表,可直接SELECT查,适合临时开、快速捞最近慢查,但表是CSV引擎,不支持索引,数据量大了查得卡 - 两者能同时开:
log_output = 'FILE,TABLE',但注意磁盘和表空间双倍消耗 - 改
log_output必须用SET GLOBAL,不能只改配置文件——它不支持热加载
为什么开了 slow_query_log 却没日志?几个硬核检查点
不是配了就完事,MySQL 有几道关卡卡住日志落地:
-
min_examined_row_limit默认 0,但如果设成 1000,那扫描行数 -
log_queries_not_using_indexes如果开着,会把没走索引的查询也塞进慢日志,哪怕long_query_time没超,这会让日志量暴增,上线前务必关掉 - 确保
general_log没开着——它和 slow_log 共享部分 IO 路径,全开可能互相干扰 - 用
SELECT SLEEP(2)测试,再立刻查mysql.slow_log或翻日志文件,比等业务慢查更可控
最常被忽略的是权限和 SELinux:CentOS 上即使路径对、用户对,SELinux 也可能拦住写操作,setsebool -P mysqld_can_network_connect_db 1 有时比改配置还管用











