一次事故

这周五凌晨进行线上数据库的切换,之前已经改成了读新库,这次是把写也切换到新库,是持续一个月工作的最后一次重要变更。

切换的操作步骤已经 review 通过并写在文档中,但实际情况远没有预料的顺利。

之前给的切换时间是 20 秒,也就是最多会有 20 秒写入失败,但实际用了两分半。然后发现新库向某映射表的同步延迟有 15 秒,这个时间是不能接受的,但回滚操作还会导致写库失败并且我们线上验证主要业务流程并没发现问题。过了一会想到前两天遇到过类似问题,是因为机器时间不一致,监控显示延迟而实际正常。查看两台机器时间,确实差了 15 秒。

在调研延迟问题的同时,发现有业务报错,另外的一张表插入失败,唯一索引冲突,经过相关同学调查,原因是部分业务除了写这次切换的表还会写其他表,而切换过程中写入两个表一个成功一个失败就导致了这种异常情况。从日志中取出插入失败的 SQL,手动修补数据后恢复正常。

继续观察业务,日志正常,测试主要业务流程也没问题。1 点半,打车回家。

4 点半还是没有睡着。

7 点醒了,第一件事情是看手机,发现有报警,还好是刚开始报警。看错误日志,认定是数据库中间件有问题,只好先修改业务方代码并紧急上线不使用中间件有问题的功能,从报警到上完线用了三十多分钟,上线后报警立即消失了。

给同事打了几个电话,继续躺回床上,没睡着。去公司后进行一些善后工作,开总结会。

吃一堑长一智吧:

  • 要一直保持警惕,尤其是这种持续时间长的任务,要知道线上的变更会有哪些影响,要找更熟悉业务的同事去聊
  • 虽然在测试环境也演练了切换操作,但要故意拉长切换时间,去发现切换中会有什么问题出现
  • 只背自己的锅

最后再记录下以前遇到的一个问题。在一次重构时发现一个很简单很小的别人写的 BUG,我顺手修改后没有测试此 BUG,上线后过了几天发现出了问题。此 BUG 存在时没有问题是因为有另外一个 BUG,两个 BUG 一起反而接口是正常的。