MySQL 8.0 binlog自动清理需同时满足三个条件:binlog_expire_logs_auto_purge=ON(总开关)、binlog_expire_logs_seconds设为非零值(过期阈值)、触发清理时机(启动/FLUSH LOGS/轮转)。仅设过期时间不等于生效,文件mtime而非事件时间决定是否删除。

MySQL 8.0 的 binlog_expire_logs_seconds 默认值是 2592000(30 天),但**这不等于“默认开启了有效清理”**——它只是设了个过期阈值,真正起作用还得看 binlog_expire_logs_auto_purge 是否为 ON,以及有没有触发清理时机。
binlog_expire_logs_auto_purge 才是开关
MySQL 8.0.29+ 默认 binlog_expire_logs_auto_purge = ON,这才是自动删除功能的总闸门。如果它被设为 OFF,哪怕 binlog_expire_logs_seconds = 604800,日志也一根不会删。
- 检查命令:
SHOW VARIABLES LIKE 'binlog_expire_logs_auto_purge'; - 启用它:
SET PERSIST binlog_expire_logs_auto_purge = ON;(推荐持久化) -
SET GLOBAL只临时生效,重启后可能回退(尤其当配置文件没写时)
过期时间不是实时检查,得靠“触发点”
binlog_expire_logs_seconds 不是后台定时轮询进程,它只在特定事件发生时才扫描并清理:
- MySQL 启动时
- 执行
FLUSH LOGS或FLUSH BINARY LOGS时 - 当前 binlog 文件大小达到
max_binlog_size,自动轮转新文件时
这意味着:即使过了 7 天,只要没触发上述任一动作,旧 binlog 就还躺在磁盘上。常见误判场景是“设了 7 天却没删”,其实只是还没轮转或没 flush。
备份锁会让过期逻辑彻底失效
使用 LOCK INSTANCE FOR BACKUP(如 xtrabackup 会自动加)期间,MySQL 会暂停所有 binlog 清理逻辑,包括基于 binlog_expire_logs_seconds 的判断。这不是 bug,是设计行为——防止备份过程中误删正在被读取的日志。
- 现象:
SHOW BINARY LOGS显示大量“已过期”文件仍存在 - 确认是否被锁:
SELECT * FROM performance_schema.metadata_locks WHERE OBJECT_TYPE = 'BACKUP_LOCK'; - 解锁后需手动
FLUSH LOGS才可能触发一次清理
最常被忽略的一点:binlog_expire_logs_seconds 判断依据是文件的 修改时间(mtime),不是日志内容里的事件时间。如果运维脚本用 touch 改过 binlog 文件时间戳,或者 NFS 挂载导致时间不同步,清理就会失准——这点几乎没人查,但线上真出过事。


















