mysql binlog日志越积越多是因为默认不自动清理,需设置expire_logs_days或binlog_expire_logs_seconds参数控制过期时间,或手动执行purge binary logs命令清理;清理后若空间未释放,可能是文件句柄被占用。

MySQL binlog 日志为什么越积越多
默认情况下,MySQL 不会自动清理 binlog,只要磁盘空间够、expire_logs_days 没设或设为 0,所有 binlog 都会一直保留。主从复制、误删恢复、审计等场景依赖它,但没人管就会撑爆磁盘——尤其是高写入业务,一天生成几十 GB 很常见。
设置 expire_logs_days 是最稳妥的自动清理方式
这个参数控制 binlog 自动过期天数,生效后 MySQL 每次执行 FLUSH LOGS 或每小时主动检查一次,删除早于指定天数的文件。注意它只对「非当前正在写的 binlog」生效,不会删掉 mysql-bin.000001 这种还在用的日志。
-
SET GLOBAL expire_logs_days = 7;立即生效,但重启后丢失(需写进配置文件) - 永久生效要加到
my.cnf的[mysqld]段:expire_logs_days = 7 - MySQL 8.0+ 推荐用
binlog_expire_logs_seconds(精度秒级),例如binlog_expire_logs_seconds = 604800(7 天) - 设为 0 表示永不过期,等同于不清理;设太小(如 1)可能导致从库 IO 线程拉不到日志而报错
Got fatal error 1236
手动执行 PURGE BINARY LOGS 快速释放空间
当磁盘告急、或需要立刻清理某段日志时,用 PURGE 命令比等自动机制更快。它直接删文件,不走过期逻辑,但必须确保删掉的日志已不再被任何从库使用(SHOW SLAVE STATUS\G 中的 Relay_Master_Log_File 是关键参考)。
- 按时间删:
PURGE BINARY LOGS BEFORE '2024-05-01 00:00:00'; - 按文件名删:
PURGE BINARY LOGS TO 'mysql-bin.000123';(删掉该文件及更早的所有日志) - 执行前先查现状:
SHOW BINARY LOGS;和SHOW MASTER STATUS;看当前正在写的文件名和位置 - 不要在主从架构中盲目删
mysql-bin.000001——哪怕它很老,从库可能还没读完
清理后空间没立即释放?可能是文件被进程占用
Linux 下执行 PURGE 后 df -h 显示空间没变,大概率是 MySQL 进程仍持有已删除文件的句柄(lsof | grep deleted 可验证)。此时只需重启 MySQL 或等待它下次 FLUSH LOGS(比如做主从切换、手动执行 FLUSH BINARY LOGS),内核才会真正回收磁盘空间。
另外,binlog 文件本身是追加写,删除操作不触发碎片整理,所以清理只是移除文件引用,不是“压缩”现有文件。











