第100章 工作是为爱好兜底(1/3)
周五晚上,公司分布式集群迁移项目出了个状况——不是大问题,但很折腾人。
正式迁移的时间定在十一月中旬,这周是做最后一次全量预演。
林泠对这个项目不算陌生,从年初开始他就断断续续在跟——分布式存储集群从旧数据中心迁移到新数据中心,数据总量将近两百tb,涉及十二个业务系统、三十多个上下游接口、几百张数据库表的增量同步。
他的角色不是项目经理也不是架构师,是数据质量校验组的负责人,专门负责写迁移前后的数据一致性校验脚本,确保每一条记录在搬家的过程中没有被改坏、弄丢、或者莫名其妙地多出几个字节。
预演从周五下午六点开始启动,按照计划应该在周六凌晨六点之前跑完。
林泠没打算通宵——他的校验脚本是最后一环,等数据同步完了才轮到他上场,预计最快也要凌晨两三点才能开始跑。
他跟项目经理打了声招呼,晚上九点先回家洗了个澡睡了三个小时,闹钟定在凌晨一点。
到公司的时候整栋楼只有机房所在的六层亮着灯,走廊里空调外机的嗡鸣声在深夜显得格外响。
机房里冷气开得很足,他裹着公司发的薄羽绒马甲坐在工位上,面前三个显示器一字排开——左边是源库的监控面板,中间是目标库的状态日志,右边是他自己的校验脚本窗口。
凌晨两点半,数据同步完成。
他开始跑校验脚本。
全量校验分了十六个并行线程,每个线程负责扫描一部分数据区块,计算源库和目标库的哈希值然后逐一比对。
跑了一个多小时,到凌晨三点四十分的时候,第十六号线程跳了一个警告——三个区块校验失败。
三百万条记录里只有三个区块校验失败,比例小到可以忽略不计,换成别人可能就直接标记为“偶发异常,重跑即可”然后关掉屏幕回家睡觉了。
但林泠没有。
他把这三个区块的源库数据和目标库数据分别导出来,在本地开了一个临时数据库,逐条比对。
因为他知道一个原则:凌晨三点发生的校验失败最值得警惕。
那个时间点正好是数据库自动备份任务和增量同步任务同时运行的窗口期,两个高负载任务叠加,存储节点的Io压力会达到全天峰值。
如果校验失败跟Io峰值有关,说明现有的校验脚本在极端负载下可能存在漏判风险——不是bug,是边界条件没覆盖到。
而迁移正式跑的时候数据量比预演大一个数量级,偶发错误的比例哪怕不变,绝对值也会被等比放大。
到时候再排查就不是凌晨三点蹲机房的问题了,是整个业务系统可能要回滚。
他在机房的冷气里蹲到半夜四点,一行一行地翻那三个区块的比对日志。
源库和目标库的数据一模一样,字段数、记录数、主键值全部对得上,但哈希值就是不一致。
他把哈希计算的中间过程拆开一步步排查,最终发现了一个极其隐蔽的问题——预演用的测试数据里,那三个区块的时间戳字段存在毫秒级重复。
同一个毫秒内写入了两条不同的记录,校验脚本在分别对源库和目标库做排序比对的时候,因为两条记录的时间戳完全一致,排序顺序在两个库里出现了随机性差异。
哪一条排在前面、哪一条排在后面,取决于数据库引擎的内部实现和当时的内存状态,是不确定的。
排序顺序不确定,哈希值就不一致。
这不是数据本身有问题,是校验脚本的排序逻辑没有考虑到毫秒级时间戳重复的边界情况。
问题定位之后修复起来很快。
他在校验脚本里加了一个联合主键排序的次级排序字段——时间戳相同的情况下按主键值排序,确保两个库的排序顺序在任何条件下都严格一致。
本章未完,请翻下一页继续阅读.........