数据迁移:双写调研

9 篇文章 2 订阅
2 篇文章 0 订阅

注:没有实践过,完全是为了学习

目的

目的:将A库中N张表中的数据迁移到B库的M张表中,在B库中做分表操作。在迁移过程中要求不停服。

方案

方案:双写

具体流程

  1. 在B库中建表,在代码中实现双写的开关以及功能(读老库,增删改老库和新库)

    • 由于只读老库,所以新库中的功能实际上未对外提供数据,即使期间新库数据存在问题,依旧不影响服务功能
    • 新增操作:老库和新库都新增,因此新增的数据新老库是一致的。(新老库自动生成的主键不一致问题,可以先插入老库,得到id,再插入新库,插入数据带上id)
    • 删操作:删除操作幂等,老库数据删除;无论新库中是否存在该数据,删除操作后新库都不存在该条数据
    • 更新操作:老库数据更新;新库中若存在该条数据,则更新,新老库数据一致,若不存在该条数据,新库中没有该条数据
    • 注意,即使新库不对外提供数据,但依旧可以灰度执行
  2. 双写执行一段时间后,对比新老库数据,要求新老库对应主键的数据一致

    • 数据一致的维度:存储维度,即新老数据完全一致;业务维度:用户看到的数据是一致的
    • 存储维度数据一致的条件是什么:对应主键数据的所有字段完全一致?(update_time字段是在MySQL机器上生成的,可能不一致,是否需要在代码逻辑中传入该字段?)
    • 回答上一个问题:迁移前必须保证机器时间一致;网络延时,新库数据update_time可能会大于老库数据;所以校对数据不必对比update_time,或者设置update_time字段差别不能超过某个阈值
  3. 若双写没问题,则可以开始搬迁历史数据至新库

    • 批量迁移,然后验证数据,验证数据的方式与上述一致
    • 迁移过程中,如果同一个id新老库中都有这条数据,那么需要对比数据的update_time字段,老数据不能覆盖新数据。
      • 第一种情况:A库中的某条数据的update_time<B库中的update_time,这表示A库中的该条数据较老,不将此条数据写入新库,出现此情况的原因可能是:从A中读了数据data1,然后业务逻辑又写了AB中的该条数据,然后在将data1与B库中的该条数据比较时,发现数据较老
      • 第二种情况:A库中的某条数据的update_tim>B库中的update_time,那么将此条数据写入B库中。出现此情况的原因可能是:业务双写,先写A,迁移读了A准备写入B,双写的B还未完成。次时将A中数据写入B库,双写过程中的写B过程可能由于不满足where条件而不执行,也可能会再次执行,有update操作幂等,因此没有问题。(在写SQL时要保证一条SQL时幂等的,不能出现a=a+1的操作,若有此操作,必须使用乐观锁)
      • 第三种情况:update_time一致,不做修改
      • 第四中情况:A中的某条数据B中没有,直接写入B库
    • 多次批量迁移和对比完成后,新老库的数据应该一致
  4. 切读:从读旧库到读新库。此阶段:读新,写旧,写信

    • 切读也可灰度
    • 验证切读没有问题,此阶段可能需要一段的时间,验证切读逻辑正确性,验证机器压力等指标数据正常
  5. 清理旧数据,旧代码逻辑

    • 清理代码中迁移中针对老库的读写代码,开关代码
    • 清理老库数据

大致流程图:
在这里插入图片描述

详细流程
在这里插入图片描述

问题

  1. update_time字段通常是 ON UPDATE CURRENT_TIMESTAMP,如果库AB的机器时间不一致,或者网络时延导致同一操作update_time字段不一致如何解决
    答:机器时间提前校准
  2. 先写A后写B,B的数据update_time可能大于A,如果一个逻辑:写A,时间戳为1,写B时间戳4;又来一个逻辑,写A时间戳2,写B失败,那么B的数据将按照时间戳后与A,此时恰好历史数据搬迁则会出问题?
    答:双写是否需要分布式事务保证?手动补偿?
  3. 如果存在外键约束,新增数据可能失败
    答:一般生产环境不允许存在外键,如果存在外键,写失败也无妨,迁移历史数据时,按照依赖拓扑图迁移?
  4. 迁移前后数据结构不一致问题
    答:在DAO层,做转换,统一视图,迁移前后的数据库不一致,例如从MySQL迁移至HBase,同数据源不影响上层使用
  5. MySQL是否存在搬迁老数据的工具?存在,例如mysqldump等,可以直接让DBA迁移
  6. 如何快速配置、回滚到各个阶段?
    答:使用策略模式,配置中心

注意:该方法是调研结论,但实际上笔者并未真实使用过。
参考 https://blog.csdn.net/ronmy/article/details/65649600

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值