expire_logs_days仅控制新日志写入,不自动清理旧binlog;必须手动执行PURGE BINARY LOGS,且需注意主从同步、备份依赖和监控验证。

为什么 expire_logs_days 设了也不自动删 binlog?
因为这个变量只对「新生成的 binlog」生效,旧日志不会被 retroactively 清理。MySQL 启动时读取该值,后续仅控制“是否允许写入新日志”,不触发删除动作。
常见错误现象:SHOW BINARY LOGS 仍列出大量几个月前的文件,磁盘空间持续增长;SELECT @@expire_logs_days 返回 7,但 mysql-bin.000001 还在。
- 必须手动执行
PURGE BINARY LOGS才能删旧日志 -
expire_logs_days是软限制,不是定时任务,MySQL 不自带后台清理线程 - 如果启用了 GTID,
PURGE会自动跳过被复制节点还未消费的日志(安全机制)
怎么安全地手动清理 binlog 文件
优先用 SQL 命令而非直接 rm 删除文件——否则 MySQL 的 index 文件(如 mysql-bin.index)会不同步,下次重启可能报错 Could not open log file。
使用场景:磁盘告警、主从延迟排查后需释放空间、迁移前清理。
- 查最老可用日志:
SHOW MASTER LOGS或SHOW BINARY LOGS - 按时间删(推荐):
PURGE BINARY LOGS BEFORE '2024-04-01 00:00:00' - 按文件名删(谨慎):
PURGE BINARY LOGS TO 'mysql-bin.000123'(保留该文件及之后的) - 执行前建议先
FLUSH LOGS,确保当前日志已轮转,避免删正在写的文件
expire_logs_days 和 binlog_expire_logs_seconds 怎么选?
MySQL 8.0.11+ 引入了 binlog_expire_logs_seconds,精度更高(秒级),且会真正驱动自动清理:只要满足条件,MySQL 每小时检查一次并触发 PURGE。
参数差异:
-
expire_logs_days(整数,单位天):5.7 及以前唯一选项;8.0+ 仍兼容,但被标记为 deprecated -
binlog_expire_logs_seconds(整数,单位秒):例如设为604800= 7 天;设为0表示禁用自动清理 - 两者同时设置时,
binlog_expire_logs_seconds优先生效 - 修改后需
SET PERSIST或改配置文件 + 重启才持久化(SET GLOBAL只临时生效)
清理 binlog 时最容易被忽略的三个点
不是删完就完事。尤其在主从、备份、审计场景下,几个关键细节常被跳过,导致后续出问题。
- 从库没同步完的日志不能删:用
SHOW SLAVE STATUS\G看Relay_Master_Log_File,确保它比你要删的最老 binlog 更新 - Percona XtraBackup 或 mysqldump --master-data 依赖当前 binlog 位点,删太快会导致备份无法恢复
- 监控脚本如果只看
df -h,可能误判——binlog 占用的是文件系统空间,但innodb_buffer_pool_size等内存参数不受影响,别因此调小缓存
自动清理不是一劳永逸的事。MySQL 不管你有没有备份策略、有没有下游订阅服务,它只认自己的规则。配了 binlog_expire_logs_seconds 也得定期验证 SHOW BINARY LOGS 输出是否符合预期。


















