引言
大家好,我是吃货无罪,一名虔诚的初级javaer,该文章仅用来记录线上一次宕机排查,不喜轻喷,拜托了!
故障排查
周四早上7点,迷迷糊糊之际,被运维电话惊醒,打开手机,几十条告警信息瞬间弹出,大致有如下几条
- 线上mysql主从连接断开
- 负责线上写服务的mysql宕机
- 线上mysql写服务器磁盘空间使用超过90%
看到这里,双眼一黑,由于公司数据相当大一部分是凌晨接收或生成的,并且如果不及时恢复服务会导致app处于瘫痪状态,所有赶紧马不停蹄赶到公司解决这次的生产事故
定位问题
-
是否由于服务器本身磁盘空间不足以支撑正常的mysql数据更新?
从和运维的沟通中得知,本次导致mysql服务挂掉的主要原因是由于磁盘空间不足,第一时间查看了近几天的mysql磁盘空间使用情况,主要查看binlog的每日空间占用,经过排查,当天剩余的磁盘空间完全可以支撑正常的数据入库,所以可以确定宕机的原因不是服务器磁盘空间不足导致的,而是由于mysql进行了某种数据操作占用了大量的磁盘空间,最终导致无更多的磁盘可用空间,进而mysql宕机
-
当日生成了大量的binlog文件
大概每分钟就会生成1GB左右的binlog文件,所以初步判断可能是数据库进行了大量的数据更改操作,导致binlog记录的内容过多,进而导致磁盘空间大量被占用,为了优先保证线上服务的正常提供,清理了近几日的binlog文件,重启了mysql服务,将主从同步恢复
-
分析binlog定位数据更新频繁的表
使用my2sql工具在从库上进行binlog的解析,这个工具是一款开源工具,可以通过对binlog进行事务、DML操作统计,也可以用来生成回滚SQL,经过分析,存在一个用来存储简评信息的表在每个binlog内都进行了大概200W次的数据更新,所以接下来就是分析为什么会进行这么频繁的数据更新操作
-
触发型更新简评信息(该表大概1000W左右数据量)
经过分析,该简评表每日会触发多次的更新,每次更新会将历史的数据effective字段置为false,而当日符合更新条件的记录过多,并且binlog采用ROW模式,所以每次执行SQL更新语句都会将每一条记录的更新进行记录,最终导致binlog存储的记录过多,进而占用大量的磁盘空间
问题修复
通过询问组内大佬得知该简评表已经没有业务调用,所以直接粗暴的将该表的数据更新调用去除,为了避免类似情况的再次发生,决定对服务器进行扩容,即使再出现类似情况,也可以在接收到报警后有充足的磁盘空间可以使用
总结
算是第一次独立处理线上突发的生产事故,中间也有处理不完善的地方,但是对于该类故障排查也有了一定的思路,不像刚开始一样完全没有思路,好啦,这篇文章就到这里啦,非常感谢my2sql作者的开源项目。
我是吃货无罪,一名虔诚的初级javaer,下期再见啦!