mysql 8中binlog自动过期依赖binlog_expire_logs_seconds(推荐,默认30天)和binlog_expire_logs_auto_purge(默认on),expire_logs_days已弃用;参数优先级为后者>前者>旧参数,且自动清理仅在启动、flush logs或binlog轮转时触发。

MySQL 8.0.26 及以后版本才支持 expire_logs_seconds,旧版本(包括所有 5.7 和大部分 8.0 早期版本)仍必须用 expire_logs_days;直接设 expire_logs_seconds 会报错或被忽略。
为什么 set global expire_logs_seconds 不生效
MySQL 在 8.0.26 才正式引入 expire_logs_seconds(替代已弃用的 expire_logs_days)。你执行 SET GLOBAL expire_logs_seconds = 604800 后查不到变化,大概率是因为:
- 你的 MySQL 版本低于 8.0.26(比如 8.0.23、5.7.39 等),该变量根本不存在
- 你误拼了变量名(如写成
expire_log_seconds或expire_binlog_seconds) - 你没用
SHOW VARIABLES LIKE 'expire%'验证变量是否存在,只看了expire_logs_days的值
运行 SELECT VERSION(); 和 SHOW VARIABLES LIKE 'expire%'; 是最可靠的判断方式。
旧版本只能用 expire_logs_days,且修改后不立即清理
expire_logs_days 是兼容性最广的参数,但有三个关键限制:
- 它只控制“过期阈值”,不是定时任务:MySQL 不会在每天零点自动删 binlog,而是等到触发日志轮转(如
FLUSH LOGS)、重启、或 binlog 文件大小达max_binlog_size时,才检查并清理过期文件 - 设为 0 表示永不清除(默认值),磁盘可能被撑爆,生产环境严禁保留 0
- 修改后需手动触发一次
FLUSH LOGS才能加速清理(尤其当当前 binlog 还很小时)
示例(设为 7 天):
SET GLOBAL expire_logs_days = 7; FLUSH LOGS;
MySQL 8.0.26+ 正确使用 expire_logs_seconds
新参数以秒为单位,精度更高,但行为逻辑不变——仍依赖轮转触发。注意:
- 必须同时 unset
expire_logs_days(设为 0),否则expire_logs_days优先级更高,expire_logs_seconds被忽略 - 推荐在配置文件中设置,避免实例重启后失效:
[mysqld]expire_logs_days = 0expire_logs_seconds = 604800 - 不能设为负数或非整数;最小有效值是 3600(1 小时)
验证是否启用成功:
SHOW VARIABLES LIKE 'expire_logs%';
输出应只显示 expire_logs_seconds 非零,且 expire_logs_days 为 0。
真正要删 binlog,别只靠参数
无论用哪个参数,都存在延迟。紧急释放磁盘空间时,应主动清理:
- 按文件名删:
PURGE BINARY LOGS TO 'mysql-bin.000055'; - 按时间删(注意时区!):
PURGE BINARY LOGS BEFORE '2026-04-05 00:00:00'; - 删完后立刻
SHOW BINARY LOGS;确认,避免误删正在使用的日志(如主从同步中未消费完的)
最易被忽略的一点:purge 操作不可回滚,且会阻塞后续 DDL/DML 直到完成——大 binlog 文件建议在低峰期执行。











