MySQL 8.0 必须显式配置 binlog_expire_logs_seconds 并确保 log_bin=ON、binlog_expire_logs_auto_purge=ON,否则自动清理失效;需写入配置文件并重启生效,不可仅用 SET GLOBAL,且清理仅在启动、FLUSH 或轮转时触发。

MySQL 8.0 搭建时必须显式配置 binlog_expire_logs_seconds,否则默认虽为 30 天(2592000 秒),但若 log_bin 未启用或 binlog_expire_logs_auto_purge 为 OFF,实际等于禁用自动清理——磁盘爆满是大概率事件,不是小概率意外。
确认 binlog 已启用且自动清理开关打开
刚初始化完 MySQL 实例,别急着改参数,先验证基础条件是否满足:
-
SHOW VARIABLES LIKE 'log_bin';必须返回ON;如果为OFF,binlog_expire_logs_seconds再怎么设都无效 -
SHOW VARIABLES LIKE 'binlog_expire_logs_auto_purge';必须为ON;这是总开关,优先级最高,设成OFF就直接绕过所有过期逻辑 -
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';若返回0或NULL,说明没生效,不能依赖“默认值”
写入配置文件而非只靠 SET GLOBAL
SET GLOBAL binlog_expire_logs_seconds = 2592000 确实能立刻生效,但 MySQL 8.0.11+ 重启后丢失——生产环境绝不能这么干。正确做法是编辑配置文件(如 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf):
[mysqld] log_bin = ON binlog_expire_logs_seconds = 2592000 binlog_expire_logs_auto_purge = ON max_binlog_size = 268435456
注意三点:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 必须把
expire_logs_days彻底删掉或设为0,否则 MySQL 8.0.23+ 启动时报错ERROR 3683 (HY000) -
max_binlog_size建议设为 256MB(268435456),避免单个 binlog 过大拖慢轮转和清理节奏 - 改完必须重启 MySQL(
systemctl restart mysqld),8.0 不支持该参数热加载
验证是否真正生效,而不是“看起来设了”
重启后连上 MySQL,执行三步检查:
-
SELECT @@binlog_expire_logs_seconds;—— 应返回你设的值(如2592000),不是0或空 -
SELECT @@binlog_expire_logs_auto_purge;—— 必须是1(即ON) -
SHOW BINARY LOGS;—— 查看当前 binlog 列表,记下最老文件名(如mysql-bin.000001),再用stat /var/lib/mysql/mysql-bin.000001看它的修改时间;等几小时后再次SHOW BINARY LOGS,若最老文件已滚动更新,说明轮转机制跑通,过期清理才可能触发
清理不是定时任务,别等它“自动发生”
即使全部配对,MySQL 也不会每天零点扫描并删日志。清理只在三个时机触发:
- MySQL 启动时
- 执行
FLUSH BINARY LOGS时(可手动运行一次加速验证) - 当前 binlog 文件大小达到
max_binlog_size,自动轮转时
这意味着:如果你的业务流量极低,binlog 几天都不满 256MB,又没从库连接、也没手动轮转,那过期 binlog 就一直堆着不动——直到某次突然写满或重启才“集中爆发”。所以搭建完建议立刻执行一次 FLUSH BINARY LOGS,让清理逻辑走一遍。










