背景
模块A需要改造由原有的表TA1换成TA2,在这种情况下模块B的表TB1中TBColumn1中数据要变更。
数据迁移要考虑的点
1.尽量线下迁移(减少发布新版本代码后 旧数据不可用的范围)
2.尽量不动原有的数据,在保留原有数据的基础上,任何时候都可以回滚代码(数据非常重要)。
3.尽量少的人工操作。
由于尽量线下刷库的原则,所以我们在B模块表TB1中增加TBColumn2列存储迁移后的数据,此时B模块老代码引用TBcolumn1新代码引用TBColumn2,所以可以随时切换。(又是一个空间换时间的方法)
根据上面几点的考虑,我们采用线下全量刷库 + 线上自动增量同步(定时任务)。
具体逻辑是:
1. A 模块线下刷库(更新数据库DDL脚本同时迁移数据),同时提供映射表给B。
2. B 模块线下刷库(更新数据库DDL脚本同时迁移数据)。
3. A ,B模块同时发布代码。
4. A模块中定时任务扫描 就代码产生的增量数据同步刷新,同时同步通知B模块更新。
//当然也可以B模块主动去A模块查询增量就数据。
5. 迁移完成后删除 A,B 模块中冗余(无用)的列,比如B模块中删除原有的TBColumn1列。
工作中具体实现示意图
迁移工作共涉及到的细节
1.以企业为维度进行迁移,灰度一家企业迁移一家。
2.迁移具体时序:刷描述、刷数据、删除旧数据。
3.支持幂:即我要多次刷程序也可以保证使用。
4.边界条件: 如果没有开通客户账户的企业过来怎么办,所以需要判断客户账户是否开启。
由于需要支持幂等且程序中任何一部都可能导致失败(有可能是网络等外部原因、也有可能是程序代码),比如刷描述(成功)-> 刷数据(失败)。那我要下次接着刷,此时刷描述就需要可以多次刷。
那么进入细节分析其应有的场景如下:
场景1:刷描述 、刷数据、成功->删除回款描述。
场景2:
1).刷描述、刷数据、失败->回款描述不用刷。
2).刷描述、刷数据(回款field的描述没有删除可以继续刷)、成功->删除回款描述。
感想
1).任何东西你要认真想一下才能带入,把细节考虑好。
2).怎么带入细节,先描述最简单的场景再逐步深入。比如(几千万个app往服务器定时上报内容)app-> server,你先考虑怎么发 -> 考虑数据量大了怎么处理 (a).如果消息不需要立马再现,可以采用队列缓冲。 b).如果立马在数据库再现可以采用热点账户,把update变成insert操作)。