mysql 5.7+ 支持 set global 动态开启慢查询,但云数据库常禁用该功能;需先确认版本和权限,动态设置仅对新连接生效,生产环境必须写入 my.cnf 并重启服务。

确认 MySQL 版本和权限是否支持动态配置
MySQL 5.7+ 支持 SET GLOBAL 动态开启慢查询,但部分云数据库(如阿里云 RDS、腾讯云 CDB)会禁用该能力,只允许通过控制台或参数模板修改。先执行 SELECT VERSION(); 确认版本,再检查是否有全局变量修改权限:SHOW VARIABLES LIKE 'slow_query_log'; 返回值若为 OFF 且你无 SUPER 或 SYSTEM_VARIABLES_ADMIN 权限,则必须改配置文件。
用 SET GLOBAL 临时开启(适合调试)
这条命令不重启服务,但只对新建立的连接生效——已有连接不会记录慢查询,这点极易误判。执行前务必新建一个终端连接验证:
SET GLOBAL slow_query_log = 'ON';-
SET GLOBAL long_query_time = 1;(注意:设为1是整数秒,MySQL 5.7 默认保留 1 位小数,实际生效值是1.0) -
SET GLOBAL log_queries_not_using_indexes = 'ON';(可选,但建议开,很多慢查询本质是没走索引)
执行后立即用新连接运行一条明显慢的 SQL(如 SELECT SLEEP(1.2);),再查日志文件路径:SHOW VARIABLES LIKE 'slow_query_log_file';,用 tail -f 观察是否写入。
写入 my.cnf 永久生效(生产环境必须)
动态设置在 MySQL 重启后失效,生产环境必须落盘。编辑 /etc/my.cnf 或 /etc/mysql/my.cnf,在 [mysqld] 下添加:
slow_query_log = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 1 log_queries_not_using_indexes = 1 min_examined_row_limit = 100
关键点:
-
slow_query_log_file所在目录需确保 MySQL 进程有写权限(常见坑:路径存在但属主不是mysql用户) -
min_examined_row_limit = 100必须配log_queries_not_using_indexes使用,否则 WHERE 条件恒假(如WHERE id = -999)也会被记日志,产生大量噪音 - 改完必须
sudo systemctl restart mysql(或mysqld),仅 reload 不生效
验证日志是否真实捕获到慢 SQL
很多人以为 SHOW VARIABLES 显示 ON 就万事大吉,其实还有三个隐藏失败点:
- 当前连接的
@@session.slow_query_log是OFF—— 因为slow_query_log是只读全局变量,不继承到会话级,必须新开连接 -
long_query_time统计的是 SQL 执行时间,不含网络延迟、解析、锁等待;SELECT SLEEP(1.2)能触发,但真实业务 SQL 可能因缓存、并发排队导致实际耗时 >1s 却未被记录 - 日志文件权限错误或磁盘满会导致静默丢弃,检查 MySQL 错误日志:
tail -n 20 /var/log/mysql/error.log,搜slow log关键字
最可靠的验证方式:用新连接执行 SELECT BENCHMARK(1000000, ENCODE('hello', 'world'));(CPU 密集型),然后立刻 grep -a "BENCHMARK" /var/log/mysql/mysql-slow.log。











