一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何应对MySQL Binlog日志文件增长过快导致的磁盘告警?

时间:2026-07-04 10:42:45 编辑:袖梨 来源:一聚教程网

必须用binlog_expire_logs_seconds(如604800秒),expire_logs_days已废弃且设则冲突或报错;PURGE前须核对主从位置,避免中断复制。

直接结论:别删文件,先查主从位置再 PURGE;MySQL 8.0+ 必须用 binlog_expire_logs_seconds,设了 expire_logs_days 反而可能失效。

确认 binlog 是否真在疯涨,以及谁在背锅

磁盘告警不等于 binlog 问题——slow_query_log 单独涨到 397G 的案例刚发生在 2026 年 4 月。先定位真实元凶:

  • du -sh /var/lib/mysql/*.log /var/log/mysql/*.log 看各日志大小,重点关注 mysql-bin.*slow-query.logerror.log
  • 执行 SHOW VARIABLES LIKE 'log_bin'; 确认 binlog 是否开启(返回 ON 才算)
  • 运行 SHOW BINARY LOGS; 查看当前 binlog 总数和总大小;如果单个 mysql-bin.000xxx 超过 1GB,且数量持续增加,基本可锁定为 binlog 问题
  • 检查是否误开了 general_logSHOW VARIABLES LIKE 'general_log'; —— 它记录每条 SQL,不用时务必关掉

紧急腾空间:PURGE 前必须核对主从位置

直接 rm mysql-bin.000042 会断主从,从库报错 Got fatal error 1236。安全清理的前提是确认所有从库都已读完待删日志:

  • 在主库执行 SHOW MASTER STATUS;,记下 File 字段(如 mysql-bin.000042
  • 逐台登录从库,执行 SHOW SLAVE STATUSG,重点看 Relay_Master_Log_FileExec_Master_Log_Pos
  • 找出所有从库中 Relay_Master_Log_File 序号最小的那个(比如 mysql-bin.000035),这就是安全边界——你最多只能 PURGE TO 'mysql-bin.000036';
  • 执行清理:PURGE BINARY LOGS TO 'mysql-bin.000036';PURGE BINARY LOGS BEFORE '2026-06-02 00:00:00';(注意时间格式必须是 Y-m-d H:i:s

防止反复爆满:MySQL 8.0+ 必须配 binlog_expire_logs_seconds

MySQL 8.0 开始,expire_logs_days 已废弃,默认值为 0(永不清除),设了也不生效。只靠 SET GLOBAL 是临时的,重启即丢:

  • 进配置文件(如 /etc/my.cnf 或宝塔路径 /www/server/mysql/etc/my.cnf),在 [mysqld] 段添加:
binlog_expire_logs_seconds = 604800expire_logs_days = 0
  • 保存后重启:systemctl restart mysqld
  • 验证是否生效:SHOW VARIABLES LIKE 'binlog_expire_logs_seconds'; —— 值必须是你设的秒数(如 604800),不是 0 或空
  • 顺手加一句 max_binlog_size = 100M,防止单个 binlog 文件过大拖慢 purge 效率
  • 源头控量:别只盯着清理,还要压生成量

    自动清理只是兜底,真正治本得减少 binlog 体积本身:

    • 查当前格式:SHOW VARIABLES LIKE 'binlog_format'; —— 若是 ROWMIXED,高频更新场景下体积可能是 STATEMENT 的 10 倍+
    • 如业务允许(无非确定性函数如 NOW()RAND()),改用 STATEMENTSET GLOBAL binlog_format = 'STATEMENT';,并写入 my.cnf 永久生效
    • 检查应用层是否有低效操作:比如用循环单条 INSERT 替代批量 INSERT ... VALUES (...), (...),这类写法会成倍放大 binlog 事件数
    • 大表全量更新/删除前,评估是否可分批 + 加限流,避免单次生成超大 binlog 文件

    最容易被忽略的是:配置改了、PURGE 也执行了,但磁盘空间没释放——大概率是旧日志文件句柄仍被 mysqld 进程占用。此时需 FLUSH LOGS; 强制切换新 binlog,旧文件才能被彻底释放。

    热门栏目