我跟你说,数据库迁移这事儿,看着简单,真上手了才知道坑有多深。上周刚帮一个老同事收拾烂摊子,他们公司把Oracle换成PostgreSQL,数据倒是导过去了,结果业务方第二天就炸了——报表数字对不上,订单状态全乱套。你说数据没丢吧,可就是不对,问题出在哪儿?迁移测试没做透。很多人觉得迁移就是搬数据,搬完就完事儿,大错特错。这活儿的关键不在“搬”,而在“搬完之后系统还能不能好好跑”。

先说说最容易被忽视的字段映射问题。不同数据库的字段类型压根儿不对等,Oracle里的VARCHAR2到PostgreSQL可能就变成VARCHAR,长度限制不一样;MySQL的TINYINT到SQL Server可能就变成BIT,取值范围直接缩水。你光看数据量对得上没用,得逐字段比对类型定义、默认值、自增规则。我见过最离谱的案例,源库有个字段是DATE类型,目标库给映射成了DATETIME,结果所有记录的时间都多了00:00:00,查询条件一写日期就全匹配不上。所以迁移测试第一件事,建一张字段映射对照表,逐项打勾,别嫌麻烦。
再说约束和索引,这玩意儿丢了更致命。源库有主键、外键、唯一约束,迁移过去要是没重建,数据倒是进去了,可后续插入更新完全失控。比如用户表有唯一索引防重复注册,迁移后索引没了,测试环境跑得好好的,一上线就出现两个相同手机号,业务直接乱套。索引这事儿还有个隐性坑——统计信息不更新。数据搬过去,优化器还按旧的统计信息走执行计划,明明该走索引的查询,偏偏全表扫描,慢得让人抓狂。所以迁移后必须重建所有约束、索引,并且跑一遍ANALYZE更新统计信息,别省这步。
存储过程和触发器,这俩是重灾区。不同数据库的SQL语法差异巨大,Oracle的PL/SQL和MySQL的存储过程写法完全两码事。你源库里有几百个存储过程,迁移脚本一跑,报错能刷屏——函数不存在、语法不兼容、游标写法不对。更麻烦的是触发器,迁移后触发时机、触发条件可能全变了。有个真实案例,源库在INSERT之前有个BEFORE触发器自动填充创建时间,迁移后这个触发器失效了,新数据全都没有创建时间,业务查询排序直接崩。所以迁移测试里,所有存储过程、触发器、函数必须逐个验证,不能只测数据,不测逻辑。
数据完整性验证这块,很多人只会对比总数,这是典型的自我安慰。总数对得上,不代表数据对得上。你得做抽样比对,按业务维度抽,比如按时间范围、按区域、按用户ID取模,每条记录逐字段比对。有个更狠的做法——做双向校验,源库和目标库同时跑同样的查询,对比结果集。这招对资金流水、订单这类核心数据尤其管用。另外别忘了NULL值,源库的NULL迁移过去可能变成空字符串,或者反过来,这种隐性差异查总数根本发现不了。
增量迁移和停窗口,这俩是时间管理的大坑。全量迁移好做,停掉业务,导完数据,启动。但很多系统不允许长时间停服,就得做增量同步。这时候你得测增量脚本的幂等性——重复执行会不会出问题?断点续传靠不靠谱?延迟多久?我见过一个案例,增量同步工具每5分钟跑一次,结果某次跑挂了,重启后从断点继续,却漏掉中间10分钟的数据,业务对账差了一千多笔。所以迁移测试必须包含断点恢复演练,模拟各种故障场景,确保增量数据不丢不重。
回滚方案,这可能是最没人愿意测但最该测的环节。迁移失败怎么办?回滚到源库。但很多团队的回滚方案就是“把数据倒回去”,真到那一步才发现倒不回去了——因为迁移过程中目标库产生了新数据,回滚会覆盖。你得设计一个可逆的迁移方案,比如保留源库只读副本、记录迁移日志、做时间点恢复。更重要的是,回滚测试要和迁移测试一样认真做,别觉得“失败才需要回滚”就敷衍了事。真出了事故,回滚脚本跑不通,那才是叫天天不应。
应用兼容性测试,这块最容易被甩锅给数据库团队。数据迁完了,应用报错,开发说是数据库问题,DBA说是应用问题。其实两边都可能有问题。迁移后应用层要重点测三件事:一是SQL语句兼容性,比如分页写法、日期函数、字符串拼接,不同数据库语法差异大;二是连接池和驱动版本,老驱动连新数据库可能报错;三是事务隔离级别,源库默认级别和目标库可能不一样,导致并发行为变化。所以迁移测试必须包含完整的应用回归测试,别只测数据层。
提醒一句,别把迁移测试当成一次性任务。上线后前两周是问题高发期,要建立监控和比对机制,每天自动跑数据比对脚本,发现差异及时处理。我见过最惨烈的案例,迁移后一个月才发现某个历史数据表的归档逻辑错了,数据被切掉了半年,补都补不回来。数据库迁移测试这事儿,本质就是把所有可能出错的环节提前暴露出来,别等上线了再赌运气。你把这些关键点都过一遍,踩过的坑越多,越知道哪些地方容易翻车。


