日志文件太大,优先别删,先查清是哪类日志在撑爆磁盘。 MySQL 有五类主要日志(binlog、error log、general_log、slow_query_log、relay log),每类清理逻辑完全不同——误删 binlog 可能断主从,直接
rmerror log 而不通知 MySQL 会导致新日志写不进磁盘,关 general_log 不用重启但关 binlog 必须重启且会丢 PITR 能力。
确认日志类型和占用来源
别猜,用命令定位真实大户:
查 binlog 总大小:SHOW BINARY LOGS;看文件名和 Size,再用
du -sh /var/lib/mysql/mysql-bin.*核对磁盘实际占用 查 error log 路径和大小:
SELECT @@global.log_error;,然后
ls -lh $(mysql -Nse "SELECT @@global.log_error")确认 general_log 和 slow_query_log 是否开启:
SELECT @@global.general_log, @@global.slow_query_log;,若为 ON,立刻查
SELECT @@global.general_log_file, @@global.slow_query_log_file;主从环境下必须先看从库进度:
SHOW SLAVE STATUS\G,重点核对
Relay_Master_Log_File和
Exec_Master_Log_Pos,确保你要删的 binlog 还没被从库读完
按日志类型分策略清理
不同日志,清理方式天差地别:
binlog:必须兼顾主从安全。MySQL 8.0+ 推荐配binlog_expire_logs_seconds = 604800(7 天),5.7 用
expire_logs_days = 7;手动清理只用
PURGE BINARY LOGS BEFORE '2026-01-21 00:00:00'或
PURGE BINARY LOGS TO 'mysql-bin.000150',严禁用
RESET MASTER(清空全部,主从必崩) error log:不建议直接
rm。正确做法是
mv /var/log/mysql/error.log /var/log/mysql/error.log.20260128+
kill -SIGUSR1 $(pgrep mysqld)(触发 MySQL 重开新文件),或配置
logrotate自动轮转 general_log / slow_query_log:无内置自动清理机制。若必须保留,用
SET GLOBAL general_log = OFF;关闭后,再删文件;长期开启务必配
logrotate,否则单日志文件可能超 10GB 导致 I/O 卡死
防复发:自动化与监控兜底
人工清理迟早漏掉,得靠机制:
加 cron 定时任务(如每天 2:00):mysql -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY)",但前提是已确认从库同步延迟 监控磁盘水位联动清理:当
df /var/lib/mysql | awk 'NR==2 {print $5}' | sed 's/%//' > 85 时,自动触发 binlog 清理脚本(注意加锁防并发)
调低日志“噪音”:设 log_error_verbosity = 2(只记 ERROR/WARNING),关
log_queries_not_using_indexes(除非正在专项优化索引),避免慢日志爆炸式增长
最容易被忽略的一点:
PURGE BINARY LOGS只删文件,不释放文件系统 inode;如果大量小 binlog 文件占满 inodes(
df -i查),即使磁盘空间充足也会报 “No space left on device”。此时需配合
find /var/lib/mysql -name "mysql-bin.[0-9]*" -mtime +7 -delete彻底清理,但务必先停写、确认从库状态、备份 index 文件。
