慢查询日志开启会引发严重io压力,因每次写入均触发fsync;log_queries_not_using_indexes应禁用,long_query_time建议调至5以上;清空日志须先关闭日志再截断文件或清表;推荐改用table输出并转innodb引擎加索引。

slow_query_log=1 直接增加随机写压力
慢查询日志不是顺序追加那么简单。MySQL 每次写入 mysql-slow.log 时,会触发一次 fsync(强制刷盘),尤其在高并发场景下,大量 SQL 被判定为“慢”后密集落盘,IO 线程立刻被压满。log_queries_not_using_indexes=1 更是雪上加霜——它让所有未走索引的查询(哪怕执行只花 0.1 秒)都进日志,实际日志量可能比真实慢 SQL 多出 5–10 倍。
- 默认
long_query_time=2在业务 QPS 高时极易失守,建议先调到5或更高 -
log_queries_not_using_indexes生产环境必须关,除非你明确需要做索引覆盖率审计 - 不要依赖
slow_query_log_file指向单个大文件,它无法轮转,只能靠人工干预
SET GLOBAL slow_query_log='OFF' 必须先于 rm -f
直接 rm -f /data/mysql/logs/mysql-slow.log 不仅无效(MySQL 进程仍持有文件句柄,磁盘空间不释放),还可能引发写入失败或进程异常。正确顺序是:
- 先执行
SET GLOBAL slow_query_log='OFF',确认SHOW VARIABLES LIKE 'slow_query_log'返回OFF - 再用
TRUNCATE TABLE mysql.slow_log(如果启用了表存储)或echo "" > /data/mysql/logs/mysql-slow.log清空文件内容 - 最后才考虑
mv归档旧日志,避免误删正在使用的文件描述符
替代方案:用 slow_log 表 + log_output='TABLE'
把慢日志存到 mysql.slow_log 表里,能规避文件系统 IO 尖峰,也方便用 SQL 查询和定时清理。但要注意:
- 启用前需确保
log_output='TABLE'且slow_query_log=1,否则表不会写入 -
mysql.slow_log默认是CSV引擎,不支持索引和高效查询,建议改成InnoDB并对start_time加索引 - 必须配合定期清理,比如
DELETE FROM mysql.slow_log WHERE start_time
磁盘 IO 飙升时优先排查 long_query_time 和索引缺失
日志暴涨往往是结果,不是根因。真正该盯的是:long_query_time 设置是否过低、是否有大量未走索引的查询在持续发生。用 mysqldumpslow -s t -t 10 /path/to/mysql-slow.log 快速定位 TOP 10 耗时语句后,重点看 EXPLAIN 输出里的 type: ALL 或 rows 过大项。
- 别只盯着日志大小,先跑
SELECT COUNT(*) FROM mysql.slow_log看是否真有海量记录 - 检查
SHOW INDEX FROM table_name,确认 WHERE 条件字段是否有覆盖索引 -
innodb_buffer_pool_size如果明显小于数据总量,会导致频繁磁盘读,间接放大慢查询比例
真正危险的不是日志本身,而是日志暴增背后那些本该走索引却全表扫描的查询——它们白天吃 CPU,晚上吃磁盘,关掉日志只是掩耳盗铃。











