那天,真是惊险。
我记得很清楚,是一个普通的周五下午,离下班还有两个小时。我还想着晚上约朋友撸串,结果,一条监控告警"数据库主从延迟严重",瞬间把我从幻想里拉了回来。
线上的问题突如其来,binlog惹的祸!
这条告警不是第一次看到,但这次很不一样。延迟竟然飙到了 20分钟,而且还在不断攀升。我们业务量虽不小,但主从差异从没这么大过。
我赶紧 SSH 登录数据库服务器,一看 show slave status\G:
当我再去查主库的 show binary logs; 时,一下懵了:
怎么回事?!之前不是一直有 binlog 吗?我一查 /var/lib/mysql 目录,瞬间明白了------binlog 满了,磁盘爆了。
我擦,这才是根本原因啊!
到底什么是 binlog?为什么会撑爆磁盘?
我们先暂停一下,跟大家简单科普一下:
binlog(二进制日志) 是 MySQL 用来记录所有对数据库进行更改的操作的日志,主要用于:
数据恢复
主从复制
审计记录
正常情况下,binlog 会不断产生文件,默认每个 1GB(可以调),文件名类似:
而这些文件是不会自动清理的,除非你明确设置了 expire_logs_days 或 binlog_expire_logs_seconds,否则,它会一直堆下去,直到磁盘炸裂。
而我这次的问题,正是因为忘记设置 binlog 过期时间,业务高峰期写入猛增,几天内就把磁盘撑爆了!
紧急处理现场:救火行动开始!
冷静下来后,我开始做几件关键的事:
- 紧急释放磁盘空间
为了先缓解服务压力,我做了两件事:
果然,mysql-bin.* 占了大头。我直接手动清除了一部分旧 binlog 文件:
或者按时间清理:
注意!别删还在用的日志,尤其是从库还没追完的,会直接导致复制失败!
- 增加 binlog 过期策略
为了避免再爆炸,我加了这两个参数:
或者:
看你 MySQL 版本(5.7 用后者,8.0 推荐前者)。
- 扩容磁盘(如必要)
我们线上是云主机,好在支持快速扩容磁盘。加了 50GB,临时缓一缓。
彻查配置,填坑补漏
火救完了,是时候复盘这个坑。
1、检查 binlog 是否开启:
2、查看当前 binlog 文件:
3、看 binlog 占用大小:
4、查是否设置了 binlog 过期时间:
你会看到:
- expire_logs_days
- binlog_expire_logs_seconds
任意一个设置了就行。
binlog 的最佳实践清单(干货来了)
1、总是设置 binlog 自动过期
推荐用秒为单位更灵活,比如:
2、启用 binlog_row_image = minimal
如果你使用的是 row 模式,这个参数可以降低 binlog 文件大小。
3、合理配置 binlog 大小限制
4、定期做备份 + 清理策略
- 每天凌晨做一次全备
- 清理 binlog:保留最近7天的,其他清理
5、主从复制配置监控
主从延迟、磁盘占用、错误日志都要有监控告警。
6、自动化清理脚本(可选)
用 crontab 定时 purge,比如:
关于主从延迟的补充建议
binlog 撑爆磁盘,还有一个"隐形杀手"就是主从延迟。为什么这么说呢?
因为如果你 binlog 多了、写得太快,从库就会同步不过来。
应对方式包括:
- 从库开启多线程复制(MySQL 5.7+):
- 开启 GTID,提升容错性
- 从库用更快的硬件(读多写少,可以用 SSD)
复盘这场事故,我学到了什么?
说实话,这次"binlog 撑爆磁盘"的事故,虽然最后我们扛住了,但我深感:
- 监控要到位:磁盘占用、binlog 增长速率都要纳入可视化监控
- 默认配置并不安全:MySQL 是"给你自由",不是"替你操心"
- 文档要更新:团队里没人记得这块配置,结果大家都以为"有人配过"
小结一波,关键知识点别忘了!
END
这事儿之后,我把这次的经历总结成了一份"Binlog 检查清单",贴在公司内部文档,避免其他同事踩雷。
也写了这个故事,分享给你们,希望你看到这篇的时候,能立刻检查一下你们的 binlog 配置,别像我一样,被一个不起眼的参数坑惨了!
如果你也踩过 binlog 的坑,欢迎留言交流,咱们一起"踩坑不重复,优化更高效"!
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!