log_output未设为FILE导致慢日志不写文件;slow_query_log_file路径需存在且MySQL有写权限;long_query_time是会话级变量,修改后需新连接生效。

log_output 不是 FILE,日志根本不会写文件
这是最常被忽略的根源:即使 slow_query_log 是 ON,只要 log_output 没设成 'FILE',MySQL 就不会碰你指定的 slow_query_log_file 路径。默认值可能是 'TABLE'(写进 mysql.slow_log 表)或 'NONE'(完全不输出)。
检查当前设置:SHOW VARIABLES LIKE 'log_output';
临时修复(重启后失效):SET GLOBAL log_output = 'FILE';
永久生效(必须加到配置文件并重启):
在 my.cnf 的 [mysqld] 段下添加:log_output = FILE
slow_query_log_file 路径存在,但 MySQL 进程没权限写
MySQL 不会报错,也不会自动创建父目录——它只是静默跳过写入。哪怕 /var/log/mysql/ 这个目录根本不存在,slow.log 也永远为空。
分三步确认:
• 查路径:SHOW VARIABLES LIKE 'slow_query_log_file';(比如返回 /var/log/mysql/mysql-slow.log)
• 查目录是否存在且属主正确:ls -ld /var/log/mysql —— 输出中第一列应含 mysql 用户和组
• 若目录缺失或权限不对:
sudo mkdir -p /var/log/mysql
sudo chown mysql:mysql /var/log/mysql
云数据库(如阿里云 RDS)通常禁用文件输出,只支持 log_output = 'TABLE',此时设成 FILE 无效。
long_query_time 改了但新查询不进日志
这个变量是会话级的。SET GLOBAL long_query_time = 1 只影响后续新建的连接;已有连接仍用旧值(比如默认 10 秒),所以你当前客户端执行的 SELECT SLEEP(1) 不会触发日志。
验证与测试建议:
• 断开当前 MySQL 客户端,重连一次
• 执行:SELECT @@session.long_query_time; 确认值已更新
• 避免用 SLEEP() 测试:系统调度可能导致耗时略低于阈值(如设 0.1 秒,实际 0.0999 秒就被跳过)
• 改用更稳定方式:SELECT BENCHMARK(10000000, ENCODE('hello', 'world'));
log_queries_not_using_indexes 或其他开关干扰判断
如果开了 log_queries_not_using_indexes,哪怕查询只花 0.01 秒、没走索引,也会进慢日志——这会让日志“看起来有内容”,却掩盖了真正耗时的 SQL。
排查命令:SHOW VARIABLES LIKE 'log_queries_not_using_indexes';
若返回 ON,立刻关掉:SET GLOBAL log_queries_not_using_indexes = OFF;
同样要检查:
• log_slow_admin_statements(让 ALTER TABLE 这类语句也进日志)
• log_slow_replica_statements(复制线程语句也记)
这些变量在配置文件中修改后,需 FLUSH LOGS 或重启才能清空缓冲、彻底生效。
真正难排查的点往往不在“有没有开”,而在于“开给谁看”——log_output 决定输出目的地,long_query_time 是会话级变量,权限问题又不报错。三者叠在一起,很容易让你盯着空文件反复怀疑配置写错了。


















