mysql二进制日志需配置binlog_expire_logs_seconds自动清理,推荐设为604800(7天),并写入my.cnf;手动purge命令须谨慎区分to与before语义,严禁在生产主库执行reset master。

MySQL 二进制日志(binlog)不会自动删除,除非你明确配置了过期策略或手动触发清理。不设防的 binlog 会持续写入、占满磁盘,最终导致 MySQL 崩溃或写入失败。生产环境必须启用自动清理,手动操作仅用于应急或精确控制。
如何设置自动清理(推荐且必须)
自动清理是唯一适合生产环境的方式,它由 MySQL 内部定时检查并安全删除,不依赖人工干预,也不影响主从复制状态。
-
binlog_expire_logs_seconds是 MySQL 8.0+ 的首选参数,单位为秒;设为604800即保留 7 天 - 执行前务必先清空已废弃的
expire_logs_days:运行SET GLOBAL expire_logs_days = 0;,否则两个参数冲突会导致清理失效 - 动态生效命令:
SET GLOBAL binlog_expire_logs_seconds = 604800;,但该设置重启后丢失,必须同步写入my.cnf的[mysqld]段落 - MySQL 不会“立刻”删文件,而是在下次 binlog 切换时或每小时检查一次;如需立即触发,可执行
FLUSH LOGS;(这会生成新 binlog 并触发旧日志清理逻辑)
PURGE BINARY LOGS TO 和 BEFORE 的区别与误用风险
这两个命令都直接删除磁盘文件,但判断依据完全不同,容易因理解偏差造成误删。
-
PURGE BINARY LOGS TO 'mysql-bin.000025';删除所有序号 小于000025的文件(即000001~000024),000025本身保留 -
PURGE BINARY LOGS BEFORE '2026-03-28 00:00:00';删除所有“已关闭”的 binlog 中最后修改时间早于该时刻的文件——注意:这个时间戳是 binlog 文件关闭时写入的时间,不是创建时间,更不是当前时间 - 正在写的当前 binlog(如
mysql-bin.000025)即使创建于 3 月 27 日,只要没关闭,就不会被BEFORE命令删掉 - 误用
BEFORE可能删掉从库还没读取的日志:执行前必须在从库上运行SHOW SLAVE STATUS\G,确认Seconds_Behind_Master接近 0,且Read_Master_Log_Pos小于主库SHOW MASTER STATUS中的Position
为什么 RESET MASTER 绝对不能在生产主库上执行
这不是“清理”,而是“格式化”:它无视所有保留策略、不检查从库状态、不归档、不可逆。
- 执行后所有 binlog 文件从磁盘彻底删除,只留下一个新文件(如
mysql-bin.000001) - 所有从库将立即报错
Could not find first log file name in binary log index file或类似 GTID 错误,复制链路永久中断 - 仅适用于单机开发库、刚初始化的测试实例,或你已决定放弃全部从库并重建复制关系的场景
- 如果只是想释放空间,应调小
binlog_expire_logs_seconds,而不是重置
真正容易被忽略的是时间语义:binlog 的“关闭时间”和“修改时间”不等于系统当前时间,也不等于你执行命令的那一刻;而从库延迟可能隐藏在 Seconds_Behind_Master = 0 的假象下——实际 Read_Master_Log_Pos 还卡在旧位置。清理前看 SHOW BINARY LOGS; 和 SHOW MASTER STATUS; 是最低成本的保险动作。











