每日分录汇总T+H上线故障复盘
背景
每日分录汇总是一个T+1的dataworks手动流程,但是现在数据量日益增多,一天数据量达到十万甚至上百万量级,T+1的运行模式会导致一次运行时间过于冗长,并且不适合其他一些即将上线的业务需求。故对每日分录汇总做T+H改造,并且从原来的手动业务流程定时任务唤起改为普通业务流程,dataworks自己定时调度。
第一轮故障
我们前一天把在测试环境跑了近两个月的流程clone到生产环境,并且做好了包括(调度时间,生产库表,其他流程下线)等检查,上线生产后需要等到第二天生成调度实例后才能开始运行,第二天回来后发现流程全部卡在拉取原始凭证节点处,一直在报数据库错误,由于我们没有详细的日志,请DBA同事排查后得知是拉取数据的切分条件对于生产数据库来说压力太大。我们发现条件的写法是将字段放在了函数里,这样的写法会导致索引失效,我就让ai帮我生成一个条件(这也埋下了一个隐患),索引问题解决了。节点续跑后发现又卡在了另一个节点处,查看报错信息后得知是字段不一致,而这个字段早在几个月前都已经在其他测试环境加上了,所以说不只是生产环境和测试环境的不一致,测试环境与测试环境之间也有可能落后几个版本,把字段加上后流程终于可以跑完了。第一轮故障解决完毕。
第二轮故障
在将第一个故障解决完后,十二点的流程正常运行,但十二点之前的流程还需要我手动重跑,由于我的流程设置的是所有与时间相关的字段取值并不是当前时间而是我设定的定时时间,这就导致十二点之后我才运行的流程跑的却是十二点之前的数据,其实本来也不会有问题,因为我们每次只取两个小时的数据,并且有去重表做兜底去重操作。但是前面ai给我埋的一个大坑就出来了,我本来的条件是只取前两个小时的数据,然而ai给我改成了前后两个小时的数据。又因为报错问题没有按时间顺序执行,导致我的去重表被击穿,这样就发生了一个非常严重的故障,所有十点到十二点的数据被流程给重新分录,大约重复生成了八万条凭证。
止血
经过排查清楚重复分录的原因后,先及时将切分条件修正,并且确定止血方案(将所有重复生成的凭证做冲销操作,把帐平掉),由于此次重复的凭证明细有大约50W条,所以原始的手动生产拉取在测试环境生成冲销凭证后再回流的操作就不可取了,我们对冲销流程(dataworks业务流程)拉取到生产环境并且针对这批重复凭证做了改造,在第一时间对这批重复凭证做了冲销操作。
故障衍生问题
在止血操作做完后,又有新的问题产生,对账发现凭证明细和凭证行对不上,这是因为我们虽然重复分录了凭证,但是明细维度我们的主键是在原始凭证生成的时候就固定的,所以虽然重复分录了,但是明细维度却在回流时因为主键一样,被insert update操作给去重掉了,但是此时就相当于我们有两份凭证两份凭证行却只有一份凭证,而且有一半的凭证行关联不到凭证明细,我们需要人造一批明细让凭证行关联上。
人造订正明细
我们本来想的是,所有十二点批次的明细都被后执行的十点的批次覆盖了,但是实际排查后发现两个批次各有一部分数据(后经排查后发现这批数据大部分都是错误的),所以第一时间想到的就是针对每个批次缺失的明细数据补上并且赋值新的主键。经过一系列操作按照批次和主键取差集洗出来的数据跟实际缺失的数据对不上。
dataworks对数据的并发操作
由于我们另一个流程对凭证进行操作时并不是从数据库中拉取数据而是取得odps分区表中的数据,这就导致,这批明细生产库里只有一份,而在分区表中有两份,这两份数据都被这个流程拉取到并做了更新操作。当这批数据回流做insert update操作时,按照我们一般的想法,两个相同的主键应该是一条数据做完update操作,另一条数据再做update操作这样的顺序操作。但是经过排查生产数据后发现当两个相同的主键可能时同时对一条数据update的,因为一条数据出现了两个批次数据的字段值。
人造明细最终方案
由于上面的并发问题我们可以粗暴的认为当前生产库的数据全部都是被并发修改过的错误数据,新方案就是将生产库的这批数据全部更新为一个批次的正确数据,再将另一个批次的数据订正主键后插入生产库,还是经过一系列拉数据,洗数据,对数据的操作后,终于是将这个大窟窿给补上了。
分锅大会
- 生产环境与各个测试环境之间的差距过大,总是会有这种测试环境没问题上了生产就报错的情况发生。
- 过于相信ai,ai生成的东西我没有对其进行多次检查验证就草草上了生产,这也进一步证明doublecheck的重要性,当局者迷,需要另一个人来做二次检查。
- 时间是最大的敌人,匆忙上线,时间分割出现问题,匆忙解决诞生出更大的问题。这些问题如果能给出足够的时间很有可能不会造成这么大的故障,那么问题来了,时间谁定的?