mysql 8.0.11+ 必须使用 binlog_expire_logs_seconds,expire_logs_days 已废弃且被忽略;5.7 及更早版本用 expire_logs_days;二者均需写入配置文件并执行 flush binary logs 才能生效,仅 set global 为临时设置。

MySQL 8.0.11+ 必须用 binlog_expire_logs_seconds,5.7 及更早版本只能用 expire_logs_days;二者都需写入配置文件才永久生效,仅 SET GLOBAL 是临时的,重启即丢失。
如何确认当前生效的是哪个参数
执行以下语句可同时检查两个变量:
SHOW GLOBAL VARIABLES LIKE 'expire_logs_days'; SHOW GLOBAL VARIABLES LIKE 'binlog_expire_logs_seconds';
结果中值非 NULL 且非默认值(expire_logs_days 默认为 0,binlog_expire_logs_seconds 默认为 2592000 即 30 天)的那个,才是当前起作用的清理策略。注意:MySQL 8.0.11+ 会优先使用 binlog_expire_logs_seconds,即使 expire_logs_days 也被设了值,后者会被忽略。
配置文件写法与生效逻辑
编辑 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf,在 [mysqld] 段下添加:
- MySQL 8.0.11+:
binlog_expire_logs_seconds = 604800(保留 7 天) - MySQL 5.7:
expire_logs_days = 7
关键点:
- 修改后无需重启 MySQL,但需执行
FLUSH BINARY LOGS触发一次日志轮转,让 mysqld 主动扫描并清理过期文件 - 清理不是“定时任务”,而是由 mysqld 在启动、日志轮转或每小时左右主动触发,所以改完不 flush 可能要等一小时才看到效果
- 若配置写错位置(比如漏掉
[mysqld]段)、拼写错误(如binlog_expire_log_seconds少个s),该参数将静默失效,SHOW VARIABLES仍显示默认值
主从环境下必须校准保留时长
如果主库设置了 binlog_expire_logs_seconds = 604800(7 天),但从库复制延迟已达 10 天,那么从库还没读的日志可能已被主库自动删掉,I/O 线程立刻报错停住,典型错误是:Could not find first log file name in binary log index file。
安全做法是:
- 在每个从库执行
SHOW SLAVE STATUS\G,记下Relay_Master_Log_File字段值(如mysql-bin.000120) - 取所有从库中该字段序号最小的那个(比如
.000115、.000120、.000118→ 安全边界是.000115) - 主库上至少保留到该文件名之后的日志,换算成时间:估算
.000115的生成时间,再加缓冲(如 +2 天),设为binlog_expire_logs_seconds值
换句话说,binlog_expire_logs_seconds 的数值必须大于「最长从库延迟 + 预留缓冲」,不能只按业务需求拍脑袋设。
常见误操作与后果
以下行为看似省事,实际高危:
- 直接
rm -f /var/lib/mysql/mysql-bin.*:破坏 binlog 索引文件mysql-bin.index,导致SHOW BINARY LOGS报错,主从同步中断,备份恢复失败 - 执行
RESET MASTER:清空所有 binlog 并重置序列号,所有从库立即断连,无法继续同步,除非重建复制 - 仅用
SET GLOBAL expire_logs_days = 7而不写配置文件:MySQL 重启后变回0(永不过期),磁盘可能某天突然爆满 - 在
my.cnf中写expire_logs_days = 0却以为“关掉了自动清理”:其实是“永不清理”,等于没设
真正需要“关闭 binlog 清理”的场景极少,多数时候是想关 binlog 本身——那应该注释或删除 log-bin 行,而不是调 expire_logs_days。











