两边数据对不上,抽样比对和分段核对要配合着用
同步跑着跑着,总会有人发现某条数据在两边不一样。这时候忌讳的是直接把源端的数据覆盖过去,因为不知道哪边才是对的,也不知道差异是怎么来的。一、差异从哪来
一类是漏了,某次改动没同步过去;一类是重了,同一条被写了两遍;还有一类是值不一样,字段转换或者默认值填错了。三类的处理方式不同,先分类再动手。数据量的估算要按行宽来算,光看行数会低估网络和存储的压力。
时间差也会造成假差异。刚写入的数据还没来得及同步,这时候比对,看到的就是不一致。判断安静的办法是看更新时间,超过同步延迟的两倍还没变,才算稳定下来,这时候比才有意义。同步延迟本身是波动的,比对的时间点选在延迟低谷,比出来的结果更接近真实。比对要选那些安静了一段时间的数据。同步的日志要能按主键查,用户反馈某条数据不对时,直接搜这个键省事。
二、先抽样
随机抽几百条主键,两边各取一次,逐字段比。抽样快,能很快判断差异是普遍的还是零星的。普遍差异多半是转换规则错了,零星差异多半是链路漏了。定期清理同步任务的历史位点,留太多只会让重启的时候不知道该用哪一个。
抽样要覆盖不同的时间段和不同的业务类型。只抽近一小时的数据,老数据里的问题就看不到。抽样也要覆盖那些改过很多次的记录,改的次数多,出错的概率自然更高,光抽新数据会漏掉它们。抽样的条数不用多,几百条就够看出趋势,关键在随机,别专挑整点写入的那一批。全量期间增量还在产生,两个过程要有交叠,不能等全量跑完才开始收增量。
三、再分段核对
按主键区间分段,每段算一个汇总值,比如条数、金额合计、很近一次改动的时间。两边对汇总,对不上的段落再拉明细。这样能把范围从几百万行缩到几千行。同步失败要能报警到人,任务停在那里不报错,比报错更难发现。
汇总的算法要一致。一边用四舍五入、一边直接截断,算出来的合计永远对不上,白折腾一场。汇总对不上但条数一致,多半是个别字段的值不同,这时候按字段分组再汇总,能快速缩小范围。汇总的字段要选那些不会因为写入顺序而变的,合计和条数可以,上界更新时间就要小心。同步任务的并发不是越高越好,源库的读能力有限,压得太狠会影响线上查询。
四、逐行比的时候注意什么
按主键排序,两边同时往下走,遇到不一致就记下来继续走。不要用一条语句做全表关联,数据量一大就跑不动。增量同步的延迟要按分位数看,平均值正常,尾部可能已经落后很久了。
比的时候忽略那些本来就允许不同的字段,比如各自的创建时间、自增编号。这些字段纳入比对,只会制造声响。允许不同的字段要写成一张清单,比对程序照着清单跳过,别靠写代码的人临时判断。比对程序要能断点续跑,几百万行跑一半断了,从头再来谁都受不了。校验可以分层做,先比条数,再比分段汇总,然后才逐行比,层层缩小范围。
五、修的时候要克制
修之前先备份那部分数据,改错了还能回去。修复的语句要限定主键范围,别一条更新语句扫全表。数据源的账号权限给到够用就行,只读的账号不要给写权限。
修复完再跑一遍比对,确认差异消失。修完不验,等于没修。修完的那批主键要单独存一份,万一后面又出问题,至少知道动过哪些地方。修复的动作尽量走审批,谁批的、改了哪张表、影响了多少行,都要留痕。目标端要有单独一道约束兜底,重复写入的时候至少不会产生两行一样的数据。
六、频率和记录
对账按天跑一次是常规做法,核心表可以缩到小时级。跑出来的结果要留档,差异的趋势比单次的数字更有用。
每一次修复都要记下原因。同一个原因反复出现,说明链路上有个地方一直没解决。原因分类不要写得太细,七八类就够,分得太细,到头来没人愿意填,反而什么也统计不出来。同步完成后不要马上切流量,先让两边并行跑一段,对比结果再决定。
对账不是为了证明数据是对的,而是为了在用户发现之前,自己先知道哪里不对。 讲得很透彻,把复杂的问题简单化,理解起来轻松了很多。 逻辑严谨,条理分明,一看就是经过认真思考和整理的内容。 没想到还有这么多细节,之前一直没注意到,感谢楼主提醒和科普。 很多建议都很接地气,能直接用在生活或工作中,实用性很强。
页:
[1]