慢查询日志未记录卡顿接口,主因是slow_query_log未启用或log_output为NONE,且long_query_time仅对新会话生效;需查运行时变量、权限、阈值设置,并结合processlist、IO监控及performance_schema定位真因。

慢查询日志里没记录,但接口明显卡顿,90%不是 SQL 不慢,而是日志根本没捕获到——slow_query_log 还是 OFF,或者 log_output 是 NONE,其他所有配置都白搭。
确认 slow_query_log 和 log_output 是否真生效
别只看配置文件写了没,得查运行时状态。MySQL 启动后不会自动加载你改的配置,尤其云数据库(如阿里云 RDS)不支持 SET GLOBAL,必须走控制台修改并确认热生效。
- 执行
SHOW VARIABLES LIKE 'slow_query_log';,返回值必须是字符串'ON',不是1、TRUE或空 - 执行
SHOW VARIABLES LIKE 'log_output';,必须是'FILE'或'TABLE';默认是'NONE',开了开关也白开 -
SET GLOBAL slow_query_log = ON;只对新连接生效,已连上的客户端不会自动继承,得新开终端验证 - Linux 下检查日志路径权限:
ls -ld $(dirname $(mysql -Nse "SELECT @@slow_query_log_file")),确保属主是mysql:mysql
long_query_time 的精度和作用域陷阱
long_query_time 不是“超了就记”,而是“执行时间 ≥ 阈值才记”,且它不向上取整——差 1ms 都不录。更麻烦的是,它只对新会话生效,当前连接仍用旧值。
- 执行
SELECT @@long_query_time;(不是SHOW VARIABLES),确认当前会话实际值 - 刚
SET GLOBAL long_query_time = 0.5;后,当前会话还得补一句SET SESSION long_query_time = 0.5;才立刻生效 - 测试别用
SLEEP(0.5):系统调度可能导致耗时 0.499s,直接漏掉;改用SLEEP(2.1)更可靠 - 线上建议从
1.0起步,观察一周后再按业务 RT(比如核心接口 P95 在 300ms)逐步下调至0.3
哪些“慢 SQL”天生不会进慢日志
MySQL 默认只记录 SELECT,且只算纯执行时间,锁等待、调度延迟、复制延迟、缓存失效抖动全不算在内。很多卡顿根源根本不在这个判定逻辑里。
- 未命中索引的
SELECT默认不记,除非显式开启log_queries_not_using_indexes = ON -
INSERT/UPDATE/DELETE即使跑 20 秒也不进日志,要开log_slow_admin_statements = ON - 存储过程里的 SQL 默认不单独判定,需
log_slow_sp_statements = ON -
SELECT COUNT(*)这类聚合,若走全表扫描但耗时略低于阈值,或因 buffer pool 预热不足导致首次极慢、后续飞快,日志里也看不到
绕过日志,实时抓正在卡住的查询
慢日志是“事后回放”,而卡顿常发生在“正在发生”的瞬间。与其等日志,不如直接查 information_schema.processlist。
- 执行
SELECT * FROM information_schema.processlist WHERE TIME > 2 AND COMMAND != 'Sleep';,找已执行超 2 秒还在跑的语句 - 重点看
State列:Sorting result、Sending data、Copying to tmp table都是典型瓶颈信号 - 搭配
SHOW ENGINE INNODB STATUS\G查最近锁等待、死锁、buffer pool 命中率,常能暴露隐性资源争抢 - 终端跑
iostat -x 1看%util(接近 100% 表示磁盘饱和)和await(>10ms 就危险),排除系统层 IO 拖累
真正难排查的,往往是那些“慢得不规律”的查询——比如第一次执行慢(冷读)、第二次飞快(buffer pool 缓存了),或者刚好卡在锁等待上(执行时间短,但排队时间长)。这些情况日志不记、processlist 一闪而过,得靠 performance_schema 或代理层埋点才能持续捕捉。


















