MySQL慢查询日志需在配置文件中设置slow_query_log=ON和slow_query_log_file路径才持久生效;临时启用用SET GLOBAL slow_query_log=ON,但仅对新连接有效;long_query_time建议设为1秒,并注意微秒精度及I/O影响。

slow_query_log 开关和基础配置怎么设才生效
MySQL 的慢查询日志默认是关闭的,光改 slow_query_log 变量不持久,服务重启就回去了。必须进配置文件(my.cnf 或 my.ini)加两行才稳:
-
slow_query_log = ON(或1) -
slow_query_log_file = /var/log/mysql/mysql-slow.log(路径得 MySQL 进程有写权限)
如果只想临时开一下调试,用命令也行:SET GLOBAL slow_query_log = ON,但注意:普通用户没这个权限,且只对新连接生效。另外,long_query_time 默认是 10 秒,线上基本没用——建议先设成 0.5 或 1:SET GLOBAL long_query_time = 1。
为什么开了 slow_log 却没记录任何 SQL
常见原因不是配置错,而是「查询没走慢路径」。比如:
- SQL 执行时间 严格小于
long_query_time(注意:单位是秒,支持小数,但精度取决于系统时钟) - 启用了
log_queries_not_using_indexes,但你又没开它,那即使全表扫描也不会记——除非真超时 - 查询被缓存命中(query cache 已废弃,但旧版本可能干扰判断)
- 客户端断连、事务未提交、或者 SQL 被优化器直接拒绝执行(比如语法错误在解析阶段就报了,根本不会进慢日志流程)
验证是否真在写日志:查变量 SHOW VARIABLES LIKE 'slow_query_log%' 和 SHOW GLOBAL STATUS LIKE 'Slow_queries',后者计数非零,说明日志逻辑已触发。
分析 slow log 文件时别被 microseconds 坑了
MySQL 5.7+ 默认把 Query_time 记到微秒级,像 Query_time: 1.234567,看着像 1.2 秒,其实是 1.234567 秒。但很多老工具(比如 mysqldumpslow)默认只认毫秒格式,会截断或解析失败。
- 确认格式:
head -n 5 /var/log/mysql/mysql-slow.log看第一行有没有microseconds字样 - 如果要用
mysqldumpslow,加-s t -t 10是常规操作,但遇到微秒日志得配--verbose或升级到较新 MySQL 版本(8.0.22+ 更兼容) - 更稳的替代方案是用
pt-query-digest(Percona Toolkit),它自动适配各种时间精度,还带聚合和索引建议
线上环境开启 slow log 的实际代价有多大
开日志本身不卡数据库,但写磁盘是同步的(除非你用 log_output = TABLE 写进 mysql.slow_log 表,那又涉及 Innodb 刷脏页压力)。关键影响在两点:
- 每条慢查询多一次 fsync,高并发下 I/O 毛刺明显,尤其日志放在机械盘或与数据目录共用磁盘时
-
long_query_time设太低(比如0.1),会导致日志爆炸,磁盘满、解析变慢、甚至影响FLUSH LOGS
折中做法:日常设 long_query_time = 2,出问题时动态调到 0.5 并搭配 SET GLOBAL log_output = 'FILE,TABLE',查完立刻切回去。别长期开着 0.1 秒阈值。



















