在产品迭代初期或者系统重构时期,业务模型的调整带来数据结构的变化,数据迁移不可避免。做好数据迁移需要考虑周全,且准备充分,做好预案,否则如果出现数据不一致问题,纠错成本高,同时核心业务数据的错误,会引起客户/业务方的投诉,团队也会承受巨大的压力。
本文结合最近一个实际项目的数据数据迁移过程,讲述了踩过的坑,加上自己的一些思考得出的一些方法论,最后给出了数据迁移个脚本的一个实例
目标确保新客户端访问新业务模型时能否正常查询之前的数据,如订单等;不会出现数据不一致。
原则影响可控 —— 只对需要迁移对数据做修改,不能影响到其他数据;不到万不得已,不会允许停机迁移数据,因此迁移窗口期越短越好,减少迁移窗口期用户行为带来的数据问题;
可回退 —— 一旦发现迁移数据有问题,可以回退到之前的数据状态;
可追溯 —— 出现问题,能够有日志或者备份数据可查;数据库的binlog,迁移程序的log可以作为依据;
可测试 —— 迁移方案必须可测试,要满足可测试,那么迁移方案必须是通用型的方案。
思路先备份,再迁移;
迁移后需要做数据比对,确保数据一致性;
出现问题,考虑是否做回退【并不是所有场景都能直接回退】;
如果业务量大,为避免用户行为和数据迁移产生冲突,考虑停服务迁移。
步骤备份 —— 将待迁移数据备份到bak表,任何在迁移过程中会被修改的数据应当被备份,任何在insert场景被当着原数据使用的数据应当被备份;
迁移 —— 迁移脚本 / 程序 只对bak表中的目标数据做操作;
验证 —— 迁移完成后,需要做数据核对,确保数据一致性;
回退 —— 回退脚本同样只对bak表中的目标数据做操作,且行为和迁移脚本行为相反。
方案的选择 数据库脚本在数据量小,业务场景简单的情况下非常适合,简单轻量级,通过sql脚本完成数据迁移非常合适。但如下几点需要认真思考:
能否写成通用sql?如果不能放弃;因为为不同环境准备不同的脚本,破坏了‘可测试’这一原则;
被操作的数据量是否太多?如果过多(通常超过1万条就很多了),可能导致脚本提交超时;
业务场景是否复杂?如果涉及到的表过多(超过3张),脚本的执行存在先后顺序,这时候通过人为保证,风险会大大增加;
测试环境和线上环境的sql执行工具/环境是否一致?如果不一致(很多公司的DBA工具会对一些语法和格式作出限制,比如不能有换行,注释中不能有半角分号等),则也会破坏掉‘可测试’这一原则;
线上sql执行流程是否冗长?如果流程冗长(公司的流程可能要求需要TL和DBA的审批,DBA作为第三方资源依赖不可控),且脚本多,会拉长数据迁移的窗口期,业务风险大大增加,破坏了‘影响可控’的原则。
迁移程序和‘数据库脚本’方法相反,撰写的‘迁移程序’能够避开这些缺点,更适合于业务场景复杂,数据量大的场景。
方案对比
项
脚本
程序
备注
通用性
不完全
完全
如:依赖第三方数据时,脚本无法做到通用
复杂场景支持
不适合
适合
复杂业务场景脚本不适合,如循环调用,第三方系统数据,多表依赖等
大数据量支持
不适合
适合
大数据量可能导致脚本提交超时,通常超过1万条不宜使用脚本,大多数dba工具通常也会对操作的数据量做限制
开发成本随复杂度增长