MySQL 8.0默认binlog永不清除,必须设binlog_expire_logs_seconds(expire_logs_days已失效)并开启binlog_expire_logs_auto_purge,配合FLUSH LOGS才能生效;手动清理须用PURGE BINARY LOGS TO,严禁RESET MASTER。

MySQL 8.0 的 binlog 默认永不清除,不配 binlog_expire_logs_seconds 就一定会撑爆磁盘——这不是预警,是已发生的事实。
确认当前 binlog 清理是否真正启用
别信配置文件里写了就生效。必须进 MySQL 查实况:
- 运行
SHOW VARIABLES LIKE 'log_bin';,返回ON才说明 binlog 真启用了 -
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';返回0或空值?那自动清理完全关闭 -
SHOW VARIABLES LIKE 'binlog_expire_logs_auto_purge';必须是ON,否则设了秒数也白搭 -
SHOW BINARY LOGS;看总大小,File_size 加起来超 2GB 就该动手了
必须用 binlog_expire_logs_seconds,expire_logs_days 已失效
MySQL 8.0.11+ 中 expire_logs_days 被官方弃用,设了不报错但不生效,还可能悄悄记 deprecation warning 到 error log(你大概率没开监控)。
- 7 天 = 604800 秒,这是最常用值;30 天 = 2592000 秒
- 临时生效:
SET GLOBAL binlog_expire_logs_seconds = 604800;,但重启即丢,仅用于验证 - 永久生效:编辑宝塔路径
/www/server/mysql/etc/my.cnf(不是/etc/my.cnf),在[mysqld]段末尾加两行:binlog_expire_logs_seconds = 604800<br>binlog_expire_logs_auto_purge = ON
- 如果之前设过
expire_logs_days,顺手清掉:SET GLOBAL expire_logs_days = 0;,避免冲突 - 改完必须重启:
systemctl restart mysqld,再查变量确认已更新
PURGE BINARY LOGS TO 是手动清理唯一安全方式
自动策略只管“未来”,已堆积的旧日志不会回溯删除。磁盘告急时得手动干预,但误删一条就断主从——PURGE 是永久删除、不可回滚的操作。
- 先在每个从库执行
SHOW SLAVE STATUS\G,记下Relay_Master_Log_File值(如mysql-bin.000120) - 取所有从库中该字段的最早序号(比如
.000120、.000123、.000125→ 安全边界是.000120) - 主库执行:
PURGE BINARY LOGS TO 'mysql-bin.000120';(注意:不删.000120本身) - 绝对不要用
RESET MASTER—— 它会清空全部 binlog 并重置序列号,从库全中断 - 执行前务必先
SHOW BINARY LOGS;确认目标文件存在,避免输错序号(比如把000120写成00012)
FLUSH LOGS 才能触发立即清理
动态设置 binlog_expire_logs_seconds 后,MySQL 不会马上删文件。它只在三个时机检查过期:启动时、FLUSH LOGS 时、或当前 binlog 写满触发切换时。
- 想立刻释放空间,必须补一句:
FLUSH LOGS; - 该命令会强制生成新 binlog 文件(如从
mysql-bin.000200切到mysql-bin.000201),同时触发对旧文件的过期扫描和删除 -
PURGE BINARY LOGS BEFORE按文件“关闭时间”删,这个时间戳不直观,容易误判;TO按序号删,逻辑清晰、可预测,更稳妥 - 真正容易被忽略的是:
binlog_expire_logs_seconds只对「非当前正在写的 binlog」生效,不会动mysql-bin.000xxx这种活跃日志


















