MySQL亿级数据平滑迁移双写方案
1、上线双写改造后的业务代码,上线时只读写老库
2、使用数据同步工具从老库全量+增量迁移到新库
3、停止同步程序,然后开启双写
读开关:只读老库
写开关:双写
新老库查询结果对比开关:开
老库追上新库后,对数据做一次全量校验,避免出现数据不一致的情况。此外还需要开启新老库查询结果对比开关,通过日志监控观察新老库的查询结果是否一致。
这里选择先停止同步,再切换到双写,中间丢失的数据使用对比&补偿任务恢复,由于此时仍然全量读老库,所以对业务不会有影响。
4、开启对比和补偿程序,补偿切换开关的过程中遗失的数据
读开关:只读老库
写开关:双写
新老库查询结果对比开关:开
对比&补偿任务:开启
该对比&补偿任务有一个缺陷,其不能处理数据被删除的情况,如果老库里的数据被删除但是新库的数据删除失败,那使用更新时间区间就无法从老库查出这条数据,自然也无法进行对比&补偿。
双写期间,如果出现删老库成功但是删新库失败的情况会有日志告警,所以不会有问题。但是停止数据同步工具 → 开启双写开关这一过程中删除的数据无法补偿。不过大部分业务用的都是逻辑删除,只有一处用了物理删除,笔者在这一处添加了日志,如果切换过程中出现删除数据的日志,就需要手动进行补偿操作。
5、数据对比正确率到达100%后,逐步切量请求到新库上
读开关:部分读新库 → 只读新库
写开关:双写
新老库查询结果对比开关:开
对比&补偿任务:开启
双写时,由于数据先写入老库再异步写入新库,因此新库的数据肯定会滞后于老库。如果将一部分读流量切换到新库上,就可能会在一些对延迟要求较高的业务场景中出现问题。
对于这种场景,我们不能采用逐步切量的策略,只能同时切换读写开关,要么只读写老库,要么只读写新库。
6、停止对比补偿程序,关闭双写,读写都切换到新库,开启反向补偿任务
读开关:只读新库
写开关:只写新库
新老库查询结果对比开关:关
对比&补偿任务:开启反向补偿
7、停止反向补偿任务,删除表迁移相关代码
停止反向补偿前,需要关注是否还有业务在读老库。观察一段时间,确认老库没有补偿任务以外的读写流量后,可以关闭补偿任务,清理迁移过程中产生的代码,清理老库数据。