迁移后binlog暴涨主因是清理策略失效,须立即检查binlog_expire_logs_seconds(非0)、binlog_expire_logs_auto_purge(on),并安全purge;永久配置需写入my.cnf且重启,宝塔用户还需添加每日清理脚本兜底。

迁移后 binlog 突然暴涨,基本就是清理策略断了——不是配置被清空,就是新实例沿用了旧的 expire_logs_days = 0 或压根没设 binlog_expire_logs_seconds。必须立刻查、立刻配、立刻 purge,否则磁盘可能在 48 小时内打满。
确认当前清理策略是否生效(MySQL 8.0.11+ 必做)
别信迁移文档里“已同步配置”的说法,直接进 MySQL 查真实状态:
-
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';—— 如果返回空或0,说明秒级清理完全没启用 -
SHOW VARIABLES LIKE 'binlog_expire_logs_auto_purge';—— 必须是ON,否则设了过期时间也白搭 -
SHOW BINARY LOGS;—— 数一数文件个数,File_size加起来超 5GB 就得动手
注意:expire_logs_days 在 8.0.11+ 已弃用,查出来是空或 0 很正常;但如果你看到它有值(比如 30),而 binlog_expire_logs_seconds 是 0,说明老参数还在干扰,得先清掉。
主从环境 purge 前必须核对 Relay_Master_Log_File
迁移后若保留了从库角色,直接删 binlog = 中断复制。安全 purge 的唯一依据是:从库当前读到哪了。
- 在从库执行
SHOW SLAVE STATUS\G - 找到
Relay_Master_Log_File字段,例如值为mysql-bin.000156 - 回到主库,执行
PURGE BINARY LOGS TO 'mysql-bin.000157';—— 这才是安全边界
如果 Seconds_Behind_Master > 3600(1 小时),说明从库明显落后,建议先等追上再 purge,或者保守点多留一天:用 PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 1 DAY); 替代硬删文件名。
永久生效必须写进 my.cnf,不能只 SET GLOBAL
临时设置 SET GLOBAL binlog_expire_logs_seconds = 604800; 重启就失效。生产环境必须落盘:
- 编辑配置文件:
/www/server/mysql/etc/my.cnf(宝塔路径,不是/etc/my.cnf) - 在
[mysqld]段落下添加:binlog_expire_logs_seconds = 604800(7 天) - 同时确保
binlog_expire_logs_auto_purge = ON(默认就是 ON,但显式写上更稳) - 保存后执行
systemctl restart mysqld或通过宝塔面板重启 MySQL
重启后立刻验证:mysql -uroot -p -e "SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';",确认值已加载。旧 binlog 不会自动删,还得手动跑一次 PURGE。
宝塔用户务必加计划任务兜底
配置文件写错一行、升级覆盖、手误注释……都可能导致自动清理失效。宝塔用户最稳妥的做法是双保险:
- 创建脚本:
/www/server/panel/script/clean_binlog.sh,内容为:#!/bin/bash mysql -uroot -p$(cat /www/server/panel/database/default.pl) -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"
- 加执行权限:
chmod +x /www/server/panel/script/clean_binlog.sh - 在宝塔【计划任务】中添加,执行周期设为每天凌晨 2 点
这个脚本不依赖 MySQL 内部变量是否生效,只要 MySQL 能连上,就强制删 7 天前的日志——它是最后一道防线,也是最容易被忽略的一环。











