binlog 暴涨 500G?一次从磁盘告警到定位重试风暴的完整复盘
binlog 暴涨 500G?一次从磁盘告警到定位重试风暴的完整复盘
上周处理了一次 binlog 暴涨,记录一下,也算给自己留个复盘。文末附上为此写的离线小工具,需要自取。
一、事故现场
早上八点收到磁盘告警,心里咯噔一下。登上控制台一看,binlog 3 天内涨了 500G+,已经挤到备份空间。第一反应是把误操作大事务的锅先按住,然后开始排查。
先看了一个最近的 binlog 文件切片,发现一个反常现象:
一个 65MB 的 binlog 文件,时间跨度只覆盖了 12 秒业务。
正常业务即使高峰期,一个 64MB 的切片怎么也能覆盖几分钟。12 秒就刷满 65MB,说明这 12 秒里发生了一些"不正常的事"。
二、先说结论(赶时间的看这里)
- 97% 的 binlog 空间(63.5MB)被同一张表的 17 次 UPDATE 占满,平均单条 3.9MB
- 根因:某同步任务失败后进入重试风暴,每次重试都把一份 ~1MB 的 HTML 错误日志整体回写到同一行的错误详情字段
- 最极端时,同一行在 8 秒内被更新 26 次
- 修复:修掉同步任务的重试逻辑(失败快照落文件而非回写数据库),binlog 生成速率恢复正常
三、排查过程
3.1 常规手段为什么不够用
第一反应是 mysqlbinlog 直接翻。说实话一开始方向跑偏了:我怀疑是哪个批量任务抽风,朝那个方向翻了一阵没结果,绕了半小时才回头从 binlog 本身下手。但很快发现这条路也走不通:
- ROW 格式 binlog 里全是行镜像事件,
mysqlbinlog只能"翻译",几十万条事件人肉翻不现实 SHOW BINLOG EVENTS同样只给事件列表,不给体量统计- 问题本质是"谁在刷盘",需要一个按表、按行聚合的分析视角,光靠逐条看事件不行。
3.2 我的排查思路
绕了弯路之后,干脆自己写个脚本聚合,按这个思路拆解:
- 表级写入排行:每个 ROWS 事件都有 table map,按表聚合事件字节数,立刻知道"钱花在哪了"
- 热点行统计:同一行(主键相同)被反复 UPDATE 的次数,应用 bug、空转、重试风暴,在这一项上全都现形
- 大字段摘要:ROW 镜像里超长字段只报体积不报内容(如
col14=<65537 B>),定位"什么字段在塞大数据" - 大事务排行:单事件超大写入直接排出来
按这个思路跑完 65MB 切片,报告第一行就是:
jobctl.sync_error_payload UPD: 34 次 bytes: 66,259,266 evt: 130
单表占了全文件 97% 的写入量。再看热点行:同一行主键在 8 秒内被更新 26 次,每次写入 1MB 左右的大字段。高频、同行、大字段整体回写,重试风暴的特征全齐了。
3.3 顺藤摸瓜
拿着"表 + 频率 + 单次写入大小"去找应用同学,几句话就对上了。那个同步任务前一天开始失败,框架的通用重试逻辑把完整的 HTML 错误页(含堆栈、请求体)作为错误详情写回了数据库行,而且失败不会终止重试,于是形成了"失败 → 写 1MB → 再失败 → 再写 1MB"的死循环。
改法不复杂:错误快照落本地文件(或对象存储),数据库里只存引用路径;同时给重试加退避和熔断。改完第二天观察,binlog 生成速率回到正常水位。
四、复盘得到的经验
- binlog 暴涨先看"单文件时间跨度",切片越小、覆盖时间越短,说明写入越异常,这个比值比总量更早暴露问题
- ROW 格式下 mysqlbinlog 原生输出不适合做体量归因,按表/行聚合才是对的视角
- "同一行被反复刷"是应用层 bug 的强信号,重试风暴、缓存空转、计数器误写,都会留下这个指纹
- 错误详情不要塞数据库大字段,要落就落文件,库里存路径
- 长事务 + 高频 binlog 生成的组合,还会拖累 undo purge,放大问题(这次 binlog 膨胀和 purge lag 是叠加出现的)
五、顺手做了个工具
这次排查用的聚合脚本,后来整理成了一个离线小工具 binlog_analyze:
- 纯 Python 标准库,零依赖、纯离线解析,不连数据库,对生产零影响
- 输入一个 binlog 文件,几十秒输出报告:表级写入排行 / 反推等效 SQL / 热点行 TOP N / 高频语句 / 大事务排行 / 繁忙时段 / 异常信号
- Windows 下打包了单文件 exe,双击即用;也附完整源码
- 适配 MySQL 及兼容引擎(PolarDB、TDSQL、OceanBase MySQL、TaurusDB 等)的 ROW 格式 binlog
上面报告里的数据就来自它的输出(表名已脱敏)。
工具放在这里了,需要自取:
👉 https://mbd.pub/o/bread/YZaWk5hvaw==
浙公网安备 33010602011771号