上周和几位技术负责人吃饭,聊起数据库迁移这事儿。一个哥们儿拍着桌子说:“我干数据库迁移十年了,每次都觉得稳了,结果总出幺蛾子。”这话一说,座上所有人都笑了,因为每个人心里都藏着一两个迁移翻车的案例。有的把用户数据搞丢了,有的迁移后性能还不如原来,最惨的是有个团队迁移到一半发现源库和目标库的字符集编码不一致,几千万条中文数据全成了乱码,被迫回滚,项目延期三个月。

数据库迁移说难也难,说简单也简单。难的是你永远不知道哪块“云彩”会下雨,简单的是只要把方案文档写扎实,就能把百分之九十的坑提前填上。我见过太多团队,上来就撸代码写迁移脚本,结果跑到一半发现表结构对不上,或者外键约束卡住了,只能回去改方案,来回折腾。真正靠谱的做法是,在动手之前先把方案文档反复打磨,像盖房子前画施工图一样,每根钢筋的位置都要标清楚。
方案文档的第一块基石是现状梳理。很多人觉得这一步可以省,直接上手干就行。错。必须用文字把源库和目标库的全貌说清楚:数据库版本是多少?使用的是什么引擎?数据量大概多大?有没有分区表?存储过程有多少个?触发器是否仍在使用?我见过最坑的一个项目,源库里有三百多个存储过程,但实际只有二十多个被业务调用,剩下的全是历史遗留垃圾。迁移团队不知道,把三百多个全迁过去,结果目标库的版本不兼容其中一部分,上线当天就崩了。
第二步是明确迁移策略。这块儿最容易犯的错是追求一步到位,恨不得所有数据一次性切过去。现实是,业务系统通常七天二十四小时跑着,你不可能把整个库锁住慢慢搬。所以要在文档里把迁移切分成几个阶段:全量迁移、增量同步、灰度切换、正式上线。每个阶段要定义清楚时间窗口,例如全量迁移安排在周末凌晨两点到六点,这四个小时能否停服?能停多久?业务方是否同意?这些都要白纸黑字写下来,让双方签字确认。
第三步是数据验证方案。这一步被太多人忽略,总觉得数据搬过去就行,大不了跑个 count(*) 对一下条数。但条数对得上不代表数据没丢。我见过一个案例,某个表有唯一索引,源库的数据里有一条违反唯一约束,迁移脚本直接跳过,count 少了一条,却没人发现。直到业务报错才追查出来。所以文档里要写清楚验证粒度:是否对关键表的每一条数据做哈希校验?是否抽样对比业务逻辑?这些验证脚本谁来写,跑几次,结果怎么记录,都得说清楚。
第四步是回滚预案。这是保命的东西。很多团队的迁移方案里写着“如遇异常,立即回滚”,但具体怎么回滚?回滚需要多久?回滚过程中业务是否继续停服?这些不写清楚,真出事儿时只能抓瞎。我建议在文档里单独开一节,把回滚的触发条件列出来,例如数据一致性校验失败超过 1% ,或者目标库性能压测达不到源库的 80% ,或者增量同步延迟超过五分钟。每条触发条件对应具体的回滚步骤,包括回滚脚本、执行人、预期耗时、回滚后的验证方法。
第五步是性能基线对比。很多人把数据搬过去就完事,上线后才发现查询慢得像蜗牛。原因很简单:源库的索引是经过多年业务打磨的,而目标库的索引可能因为版本差异或参数配置不同,优化器走了一条完全不同的执行计划。所以文档里要写清楚迁移前后如何做性能对比:挑出业务中最核心的二十条 SQL,在源库和目标库分别跑一遍,记录执行计划和耗时,确保差异在可接受范围内。这一步应放在灰度切换阶段完成,并配套自动化脚本,不能靠人工一条条跑。
第六步是文档的版本管理和评审机制。数据库迁移方案不是个人拍脑袋写的,需要 DBA、开发、运维、业务方四方一起审。我建议把文档放到 Git 仓库里管理,每次修改都要有 commit 记录,评审时直接在 PR 上打评论。评审不通过就不能动手迁移。这个流程看似繁琐,却能过滤掉大部分低级错误。我见过一个团队,方案文档里把目标库的 IP 写错了,评审时被运维一眼发现,否则数据就要搬到别人家去了。
说一句大实话:数据库迁移方案文档不是写给别人看的,而是给自己和团队保命的。写得越细,踩坑越少。你以为的万无一失,往往只是因为你还没踩到那个坑。所以下次写迁移方案时,别嫌麻烦,把每个细节都写清楚,即使觉得“这谁不知道啊”,也要写上去。因为真正出问题时,你根本没时间去想,只能照着文档一步步操作。文档既是操作手册,也是事后定位问题的关键证据——开玩笑的,但确实能帮你快速定位问题。


