安全清理binlog的核心是依据从库Relay_Master_Log_File确定最小安全序号,仅删除其序号更小的文件,必须用PURGE BINARY LOGS命令操作,不可rm;自动清理应配置binlog_expire_logs_seconds(MySQL 8.0+),首次启用需手动PURGE。

主从复制环境下清理 binlog,核心不是“主库写了多少”,而是“从库读到了哪”。删早了会断主从,删晚了又占磁盘。安全清理的关键是先确认所有从库的同步位置,再在主库上执行 PURGE 命令。
第一步:查清每台从库同步到哪个 binlog 文件
登录每一台从库,执行:
SHOW SLAVE STATUS\G重点看 Relay_Master_Log_File 字段(不是 Master_Log_File),它表示该从库已成功执行完的主库日志文件名。比如返回:
Relay_Master_Log_File: mysql-bin.000138
说明这台从库已处理完 mysql-bin.000138 及之前的所有日志。
把所有从库的这个值列出来,找出序号最小的那个(比如 mysql-bin.000135),这就是你本次清理的安全下限——所有序号小于它的 binlog 都可以删。
第二步:在主库确认当前写入位置和可删范围
登录主库,执行:
- SHOW MASTER STATUS; → 记下当前正在写的文件名(如 mysql-bin.000142)
- SHOW BINARY LOGS; → 查看全部 binlog 列表及大小,确认总占用
安全删除上限 = 所有从库中 Relay_Master_Log_File 序号最小值的下一个文件。
例如最旧从库停在 mysql-bin.000135,那最多只能执行:
PURGE BINARY LOGS TO 'mysql-bin.000136';
(删掉 .000135 及更早的,保留 .000136 起的所有日志)
第三步:执行 PURGE 并验证空间释放
PURGE 是唯一安全的手动方式,它会同步更新 mysql-bin.index 并通知系统释放资源:
- 按文件名删:PURGE BINARY LOGS TO 'mysql-bin.000136';
- 按时间删(注意格式):PURGE BINARY LOGS BEFORE '2026-07-01 00:00:00';
执行后若 df -h 看磁盘没变化,大概率是 MySQL 进程还持有已删文件的句柄。
运行 lsof | grep deleted,如果看到大量 mysql-bin.* deleted,就证实了这点。
此时最快解法是:FLUSH BINARY LOGS;(触发日志轮转,内核真正释放空间)
第四步:配置自动清理,避免反复手动干预
MySQL 8.0+ 必须用 binlog_expire_logs_seconds,expire_logs_days 已失效:
- 临时生效:SET GLOBAL binlog_expire_logs_seconds = 604800;(7 天)
- 永久生效:编辑 my.cnf 的 [mysqld] 段,加两行:
binlog_expire_logs_seconds = 604800
expire_logs_days = 0 - 重启后验证:SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';
注意:自动策略只对“非当前正在写的 binlog”生效,已堆积的旧日志不会自动删,首次启用后建议手动 PURGE 一次。


















