MySQL 8.0.23+ 必须使用 binlog_expire_logs_seconds 控制 binlog 过期清理,expire_logs_days 已弃用且共存会启动报错;该变量为 persist-only,需 SET PERSIST 或配置文件设置,配合 binlog_expire_logs_auto_purge=ON 才生效,清理由 FLUSH BINARY LOGS 等事件触发,并受从库延迟保护。

确认 binlog_expire_logs_seconds 是否生效(8.0.23+ 必须用这个)
MySQL 8.0.23 起 expire_logs_days 已被弃用,若配置文件里还留着它,和 binlog_expire_logs_seconds 共存,MySQL 启动会直接报错 ERROR 3683 (HY000)。所以第一步不是改配置,而是查现状:
-
SHOW VARIABLES LIKE 'log_bin';—— 必须是ON,否则日志根本没开 -
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';—— 若返回0或空值,表示自动清理已禁用 -
SHOW VARIABLES LIKE 'binlog_expire_logs_auto_purge';—— 必须为ON,否则即使设了过期时间也不触发清理
注意:binlog_expire_logs_seconds 是 persist-only 变量,SET GLOBAL 会报错 ERROR 1238,只能用 SET PERSIST 或写入配置文件。
设置 binlog 保留天数(秒级换算别手误)
7 天 = 604800 秒,30 天 = 2592000 秒。别用“30 × 24 × 3600”现场心算,复制粘贴更稳:
- 动态持久化(推荐):
SET PERSIST binlog_expire_logs_seconds = 604800;(需SYSTEM_VARIABLES_ADMIN+PERSIST_RO_VARIABLES_ADMIN权限) - 配置文件方式:在
/etc/my.cnf的[mysqld]段添加binlog_expire_logs_seconds = 604800,然后重启或执行FLUSH LOGS - 该参数只控制“过期时间”,不等于“每天定时删”。清理实际由
FLUSH BINARY LOGS、从库 IO 线程连接、或 MySQL 启动时触发
如果主从延迟高(Seconds_Behind_Master > 0),正在被从库读取的 binlog 文件不会被删——得先压低延迟,再清理才安全。
配置 max_binlog_size 控制单文件体积(影响运维效率)
max_binlog_size 和过期策略完全正交。它不解决总量问题,但决定单个文件是否便于传输、压缩、排查。默认 1GB,大事务可能突破限制(事务不能跨文件):
- 建议设为
536870912(512MB)或268435456(256MB) - 动态设置:
SET GLOBAL max_binlog_size = 536870912;(重启失效) - 持久化:
max_binlog_size = 536870912写入my.cnf,再FLUSH LOGS触发轮转 - 注意:哪怕设成 1MB,若
binlog_expire_logs_seconds是 0,照样攒满磁盘
手动清理前必须检查从库状态与 binlog 位置
别一看到磁盘告警就 PURGE BINARY LOGS。清早了,从库会断在 Got fatal error 1236;清晚了,磁盘继续爆。操作前务必确认:
- 主库执行
SHOW SLAVE HOSTS;或查performance_schema.replication_connection_status,确认有活跃从库 - 从库执行
SHOW SLAVE STATUS\G,看Relay_Master_Log_File和Exec_Master_Log_Pos,记下当前已执行到的主库 binlog 文件名和位点 - 主库执行
SHOW MASTER LOGS;,确认Relay_Master_Log_File还在列表里;若已不在,说明从库落后太多,得先追上再清理 - 安全的手动清理命令:
PURGE BINARY LOGS TO 'mysql-bin.000023';(删掉该文件之前所有日志)
真正容易被忽略的是:清理不是按“天”实时发生的,而依赖外部事件触发;且 binlog_expire_logs_seconds 的值一旦设错或权限不足导致 SET PERSIST 失败,mysqld-auto.cnf 里就不会落盘——下次重启就回退到默认值 0。


















