MySQL 8.0默认开启log_bin但不自动清理,因binlog_expire_logs_seconds默认为0(永久保留);必须显式设置非零秒值(如604800)、启用binlog_expire_logs_auto_purge=ON、重启mysqld并验证生效,否则磁盘将持续膨胀。

MySQL 8.0 默认开启 log_bin,但默认 不自动清理 ——binlog_expire_logs_seconds 值为 0,等同于永久保留。这不是配置漏了,是设计如此:开 binlog 安全,删 binlog 得你拍板。
binlog_expire_logs_seconds 必须显式设置且重启生效
MySQL 8.0.11+ 已彻底废弃 expire_logs_days,设它会直接报错 [3683],或静默失效。只认秒级参数:
- 7 天 =
604800秒,3 天 =259200秒 - 临时生效(重启丢失):
SET GLOBAL binlog_expire_logs_seconds = 604800; - 永久生效:编辑宝塔常见路径
/www/server/mysql/etc/my.cnf,在[mysqld]段末尾加两行:binlog_expire_logs_seconds = 604800 binlog_expire_logs_auto_purge = ON
- 若之前设过
expire_logs_days,先清掉:SET GLOBAL expire_logs_days = 0; -
改完必须重启:
systemctl restart mysqld,否则配置不加载
验证是否生效:SHOW VARIABLES LIKE 'binlog_expire_logs_seconds'; 返回值应为非零数字。
PURGE BINARY LOGS 手动清理前必须核对从库安全下限
自动策略只管“未来”,已堆积的 binlog 不会回溯删除。磁盘告急时得手动清,但删错一个文件,主从立刻中断,报错 Got fatal error 1236:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 主库执行:
SHOW MASTER STATUS;→ 记下当前File(如mysql-bin.000142) - 每台从库执行:
SHOW SLAVE STATUS\G→ 看Relay_Master_Log_File(如mysql-bin.000135) - 取所有从库中该字段序号最小的那个(比如
000135),就是你能删的最老日志 - 安全命令是:
PURGE BINARY LOGS TO 'mysql-bin.000136';(删掉000136之前全部) - 如果是 GTID 模式(
gtid_mode = ON),禁用TO,改用时间:PURGE BINARY LOGS BEFORE '2026-10-08 00:00:00';
执行后若 df -h 空间未释放,跑 lsof | grep deleted,看到 mysql-bin.* deleted 说明句柄还挂着——此时需 FLUSH BINARY LOGS; 或重启 MySQL。
binlog_format = ROW 加剧磁盘膨胀,别忽略格式影响
MySQL 8.0 默认 binlog_format = ROW,一次批量更新可能生成上千条事件,体积比 STATEMENT 高 5–10 倍。查现状:SHOW VARIABLES LIKE 'binlog_format';
- 临时切格式(确认无
NOW()、RAND()等非确定函数):SET GLOBAL binlog_format = 'STATEMENT'; - 永久生效:在
my.cnf的[mysqld]段加binlog_format = STATEMENT,重启后验证 - GTID 或含触发器/存储过程时慎用,
MIXED是更稳妥折中选择
注意:改格式不影响已有 binlog,只控制后续写入体积。
清理 binlog 最容易被忽略的点,不是“怎么删”,而是“删完空间为什么没回来”——Linux 下文件被 PURGE 后只是 unlink,只要 MySQL 进程还拿着句柄,磁盘就不会真正释放。这问题在业务低峰期尤其隐蔽,等发现时往往已满盘。

















