这次现场里,/data 一度使用到 76% ,/data/mysql/logs 占了 408G ,其中 mysql-slow.log 单文件约 397G ;处理后 /data 使用率降到 6% ,并最终将 slow_query_log 关闭、log_queries_not_using_indexes 关闭、GLOBAL long_query_time 调整为 5。
MySQL 慢查询日志暴涨导致磁盘告警:一次生产环境处理 SOP
一、问题现象
生产环境巡检时,发现数据盘 /data 使用率偏高:
df -h
现场结果显示:
/dev/mapper/vg_data-lv_data 591G 429G 138G 76% /data
继续进入 MySQL 日志目录排查:
cd /data/mysql/logs
du -sh
ls -lh
结果很直接:
-
/data/mysql/logs总占用 408G -
mysql-slow.log约 397G -
mysql-bin.000469 ~ mysql-bin.000480每个约 1.1G -
mysqld.log很小
也就是说,这次不是 binlog 把盘吃满,而是 slow log 直接长成了巨无霸。
二、原因定位
查看 MySQL 配置文件:
cat /etc/my.cnf
日志相关配置如下:
slow_query_log = 1
slow_query_log_file = /data/mysql/logs/mysql-slow.log
long_query_time = 2
log_queries_not_using_indexes = 1
这个组合在生产上风险不小:
-
开启了慢查询日志
-
慢查询阈值只有 2 秒
-
log_queries_not_using_indexes = 1也开着
这意味着,不只是"真正慢"的 SQL 会进日志,很多没走索引的 SQL 也会被持续记录。业务一旦量上来,慢日志膨胀速度会非常猛。
这次故障里,真正的高风险点其实就是这句:
log_queries_not_using_indexes = 1
它像把日志水龙头彻底拧开了。
三、处理过程
1. 先确认慢日志状态
登录 MySQL 后先核实当前状态:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';
现场确认:
-
slow_query_log = ON -
slow_query_log_file = /data/mysql/logs/mysql-slow.log
说明 MySQL 当时确实还在持续往这个文件写内容。
2. 先关闭慢查询日志
生产环境里,不建议一上来就删文件。
正确顺序是先停写:
SET GLOBAL slow_query_log='OFF';
SHOW VARIABLES LIKE 'slow_query_log';
确认结果变成:
slow_query_log = OFF
这一步非常关键。
先关日志,再处理文件,才是稳妥姿势。
3. 清空慢日志文件
退出 MySQL 后,在系统层执行:
truncate -s 0 /data/mysql/logs/mysql-slow.log
ls -lh /data/mysql/logs/mysql-slow.log
执行后,mysql-slow.log 变成了 0 字节:
-rw-r-----. 1 mysql mysql 0 /data/mysql/logs/mysql-slow.log
这里使用的是 truncate,不是 rm -f。
原因很简单:在生产环境里,truncate 更温和、更可控。
4. 验证空间是否真正释放
清空慢日志后,再次检查目录和磁盘:
ls -lh
df -h
处理结果非常明显:
-
logs目录从 408G 降到 12G -
/data使用率从 76% 降到 6% -
/data已用空间从 429G 降到 33G
这说明空间不是"看起来清了",而是真正回收成功了。
四、参数收口与复盘
日志清掉只是止血,真正要做的是防复发。
因此后续又检查并持久化调整了参数:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';
SHOW VARIABLES LIKE 'long_query_time';
SET PERSIST slow_query_log = OFF;
SET PERSIST log_queries_not_using_indexes = OFF;
SET PERSIST long_query_time = 5;
最终再看全局参数:
SHOW GLOBAL VARIABLES LIKE 'slow_query_log';
SHOW GLOBAL VARIABLES LIKE 'log_queries_not_using_indexes';
SHOW GLOBAL VARIABLES LIKE 'long_query_time';
确认结果为:
-
slow_query_log = OFF -
log_queries_not_using_indexes = OFF -
long_query_time = 5.000000
这里还有一个容易误判的小点:
你在现场中发现 SHOW VARIABLES LIKE 'long_query_time'; 仍然显示 2 ,但 SHOW GLOBAL VARIABLES LIKE 'long_query_time'; 已经是 5 。这不是配置失败,而是 SESSION 值还没变,GLOBAL 值已经生效。新连接会继承新的全局值。
五、最终结论
这次故障的根因,不是数据文件异常,也不是 binlog 暴涨,而是:
-
开启了慢查询日志
-
long_query_time设置偏低 -
log_queries_not_using_indexes开启
三者叠加后,mysql-slow.log 最终膨胀到 397G ,直接把 /data 顶到 76% 。
处理思路其实很清晰:
先定位日志目录 → 确认 slow log 状态 → 关闭 slow log → truncate 清空文件 → 验证空间释放 → 持久化调整参数。
一句话总结就是:
能把磁盘清出来,只是完成抢救;能把参数收住,才算真正收工。
六、可直接复用的命令清单
# 1. 看磁盘
df -h
# 2. 看日志目录
cd /data/mysql/logs
du -sh
ls -lh
# 3. 登录 MySQL
mysql -u root -p
-- 4. 查看慢日志状态
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';
-- 5. 关闭慢日志
SET GLOBAL slow_query_log='OFF';
SHOW VARIABLES LIKE 'slow_query_log';
# 6. 退出后清空慢日志
truncate -s 0 /data/mysql/logs/mysql-slow.log
# 7. 验证空间
ls -lh /data/mysql/logs/mysql-slow.log
df -h
-- 8. 持久化防复发
SET PERSIST slow_query_log = OFF;
SET PERSIST log_queries_not_using_indexes = OFF;
SET PERSIST long_query_time = 5;
-- 9. 验收
SHOW GLOBAL VARIABLES LIKE 'slow_query_log';
SHOW GLOBAL VARIABLES LIKE 'log_queries_not_using_indexes';
SHOW GLOBAL VARIABLES LIKE 'long_query_time';
如果你要,我可以继续把这版改成更像 CSDN/博客园发文风格 的成稿版,标题、摘要、结尾都一起润一下。