binlog_expire_logs_seconds是mysql 8.0+中控制binlog自动过期的唯一推荐参数,单位为秒,默认2592000秒(30天),需配合binlog_expire_logs_auto_purge=on生效,清理在启动、flush logs或binlog切换时触发。

binlog_expire_logs_seconds 是什么,为什么必须用它
binlog_expire_logs_seconds 是 MySQL 8.0+ 中控制二进制日志自动过期的唯一推荐参数,单位是秒。它比已废弃的 expire_logs_days 更精确——比如能设为 604800 秒(刚好 7 天),而 expire_logs_days = 7 实际可能按“日界”截断,导致多留或少留几小时。
该参数默认值是 2592000 秒(30 天),但生产环境通常要调短。只要它非零且 binlog_expire_logs_auto_purge 为 ON(默认就是),MySQL 就会在合适时机自动删过期文件,无需人工干预。
容易踩的坑:
- 不关掉旧参数就直接设新参数,会报 warning 甚至被忽略:必须先执行
SET GLOBAL expire_logs_days = 0 - 只执行
SET GLOBAL动态修改,重启后失效——必须同步写入配置文件 - 误以为设了就会“立刻删”,其实清理触发有延迟:依赖
FLUSH LOGS、binlog 切换或每小时定时检查
如何永久生效:my.cnf 配置写法
编辑 MySQL 配置文件(如 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),在 [mysqld] 段落里添加:
binlog_expire_logs_seconds = 604800 binlog_expire_logs_auto_purge = ON
注意:
-
binlog_expire_logs_auto_purge = ON必须显式写上,避免某些版本默认异常或被其他配置覆盖 - 不要写
expire_logs_days,哪怕注释掉也不建议留着,防止冲突 - 路径和文件名因系统而异,改完记得
sudo systemctl restart mysql或对应服务名
动态修改后如何验证是否生效
登录 MySQL 后执行:
SHOW GLOBAL VARIABLES LIKE 'binlog_expire_logs_seconds'; SHOW GLOBAL VARIABLES LIKE 'binlog_expire_logs_auto_purge';
确认返回值分别是 604800 和 ON。再查当前 binlog 列表和时间:
SHOW BINARY LOGS;
观察最老文件的 File_size 和创建时间(注意:MySQL 不直接显示创建时间,需结合系统文件 ls -lt /var/lib/mysql/mysql-bin.* 对照)。
常见误判点:
-
SHOW BINARY LOGS只显示“已关闭”的文件,正在写的mysql-bin.000xxx不会出现,别拿它算时间 - 系统文件时间戳是“关闭时间”,不是“创建时间”,所以
PURGE ... BEFORE的判断依据就是这个关闭时间 - 如果刚改完配置却没看到旧文件被删,先执行
FLUSH LOGS强制切换一次 binlog,触发检查
PURGE BINARY LOGS 能不能配合使用
可以,但仅限应急或精细控制场景,比如临时腾空间、或保留某次备份后的全部日志。此时仍要确保 binlog_expire_logs_seconds 已设好,避免后续失控。
两个命令的区别必须分清:
-
PURGE BINARY LOGS TO 'mysql-bin.000123':删所有序号 小于 000123 的文件(000122、000121…),000123 本身保留 -
PURGE BINARY LOGS BEFORE '2026-04-03 00:00:00':删所有“关闭时间”早于该时刻的文件,正在写的文件哪怕创建于 4 月 2 日也不会删
最关键的一条铁律:执行前务必在从库上确认 SHOW SLAVE STATUS\G 中的 Relay_Master_Log_File 和 Exec_Master_Log_Pos,确保你要删的日志已被从库完全应用——否则主从直接中断,恢复成本远高于磁盘空间。
自动策略管长期,手动命令管边界;前者防疏漏,后者防误伤。真正难的从来不是怎么删,而是怎么判断“哪些真能删”。











