MySQL binlog越积越多因默认expire_logs_days=0不自动清理,需配置过期策略或手动PURGE;error/general log不可运行时压缩,须用logrotate轮转后gzip压缩;清理后空间未释放多因文件句柄被占用。

MySQL 的 binlog 文件为什么越积越多
binlog 不会自动删除,除非你明确配置了过期策略或手动清理。默认情况下 expire_logs_days 是 0,意味着永久保留。一旦业务写入频繁、主从延迟高、或备份脚本没触发 purge,几天就能涨到几十 GB。
- 检查当前设置:
SHOW VARIABLES LIKE 'expire_logs_days'; - 查看现有日志列表:
SHOW BINARY LOGS; - 确认最近一次全量备份时间——别删掉备份依赖的 binlog
安全清理 binlog 的三种方式
直接删文件会破坏 MySQL 内部索引,必须走 SQL 或系统命令配合刷新。最稳妥的是用 PURGE BINARY LOGS,它会同步更新 mysql-bin.index 并释放磁盘空间。
- 按时间清理(推荐):
PURGE BINARY LOGS BEFORE '2024-05-01 00:00:00'; - 按文件名清理:
PURGE BINARY LOGS TO 'mysql-bin.000123'; - 启用自动清理:在配置文件中设
expire_logs_days = 7,然后重启或执行SET GLOBAL expire_logs_days = 7;
注意:SET GLOBAL 修改只对新生成日志生效,已有旧日志不会被自动 purge,仍需手动触发一次。
error log 和 general log 能不能压缩
MySQL 本身不支持运行时压缩日志,但可以轮转后用外部工具压缩归档。重点在于避免直接覆盖或截断正在写的文件,否则可能丢失日志或引发 mysqld 报错 Failed to open log file。
-
error_log可通过 logrotate 管理,配置copytruncate安全截断 -
general_log_file和slow_query_log_file同样适用 logrotate,但要确保 MySQL 有权限重开新文件 - 压缩建议用
gzip(不是bzip2),因为解压速度快,且大多数运维工具默认支持
清理后磁盘没释放?可能是 inode 占满或文件被进程占用
执行 PURGE 或 rm 后 df 显示空间未增加,常见原因是:日志文件被 mysqld 进程持续持有句柄,或误删了还在写的文件导致空间无法回收。
- 查被删除但仍被占用的文件:
lsof +L1 | grep mysql - 确认 binlog 索引是否更新:
cat /var/lib/mysql/mysql-bin.index,里面列出的文件必须真实存在 - 极端情况需重启 mysqld,但务必先确认主从同步状态和 GTID 位置
真正危险的操作是绕过 MySQL 直接 rm -f 所有 mysql-bin.*,这会导致主从断裂、恢复失败,且后续 FLUSH LOGS 可能报错。


















