上周有个朋友找我诉苦,他们公司要把一套跑了五年的Oracle系统从Windows服务器搬到Linux上,数据量接近两个T。项目组熬了三个通宵,结果迁移完发现报表模块的存储过程乱码,订单表的主键序列断档,客户对账时发现少了三天的流水。这场景听着熟悉吗?跨平台数据库迁移,看起来就是导出再导入,实际上每个环节都藏着能把人绊倒的坑。

先说最基础也最要命的问题:字符集。很多团队在迁移前根本不检查源库和目标库的字符集差异,等到数据灌进去才发现中文全变成了问号。我见过最惨烈的案例,某电商公司从SQL Server迁到MySQL,原库用的GBK,目标库默认UTF8,结果商品描述字段全部损坏,只能从备份重新恢复。正确的做法是迁移前用查询语句对比两边的字符集设置,如果源库是GBK而目标库是UTF8,必须在导出时先转换编码,而不是等导入后补救。
数据类型映射是第二个大坑。Oracle里的NUMBER(10,2)到了PostgreSQL可能变成NUMERIC,看起来差不多,但精度和舍入规则有微妙差异。更头疼的是日期类型,SQL Server的DATETIME精度到毫秒,MySQL的DATETIME默认只到秒,迁过去后时间戳被截断,日志分析直接出偏差。我建议在正式迁移前,先抽几百条代表性数据做全字段对比,把每种数据类型的映射关系列成清单,逐项确认精度、长度、默认值这些属性。
存储过程、触发器、视图这类数据库对象,往往是迁移中最耗时间的部分。语法差异只是表面问题,更深层的是逻辑兼容性。比如Oracle的PL/SQL里用了START WITH...CONNECT BY做递归查询,迁到MySQL就得改写成WITH RECURSIVE,如果业务逻辑复杂,改写过程中很容易引入bug。更隐蔽的是隐式类型转换,在源库里能跑的查询,换个数据库引擎后因为类型转换规则不同,性能可能下降几十倍。这种问题靠人工检查很难发现,建议用专门的SQL兼容性分析工具先扫一遍。
数据一致性校验是迁移后最容易被忽视的环节。很多团队导入成功就宣布大功告成,结果过了几天才发现某些表少了行。我做过一个项目,迁移后对账发现订单明细表少了八千多条记录,排查半天才找到原因:源库有级联删除操作,导出时用了不一致的快照,导致部分关联数据没导全。正确的校验方式不只是对比行数,还要做抽样比对,关键业务表全量比对。可以写脚本分别从源库和目标库生成CRC校验值,再逐表比对。
迁移过程中的业务中断时间,是很多团队没提前规划的。数据库跨平台迁移不是把文件拷过去就完事,需要停机导出、传输、导入、验证,整个流程可能长达十几个小时。如果你的业务要求停机窗口不超过两小时,就得考虑增量同步方案。我见过一个聪明的做法:先做全量迁移,然后用ETL工具记录源库的增量日志,在正式切换前持续同步增量数据,在停机窗口内只同步几分钟的数据变更。
权限和账号体系在迁移时也容易出问题。不同数据库的用户管理方式差异很大,Oracle的账号绑定在实例上,MySQL的账号分主机和用户两层,SQL Server还有架构和角色体系。直接复制权限脚本往往会出错,比如Oracle的GRANT语法和MySQL的GRANT语法完全不同。我建议按照最小权限原则重新梳理账号体系,在目标库上重建所有账号和角色,而不是试图原样搬运。
还有一个很多人忽略的细节:序列和自增主键。Oracle用SEQUENCE,MySQL用AUTO_INCREMENT,PostgreSQL用SERIAL或IDENTITY。迁移后如果没正确设置新的序列起点,插入新数据时就会因为主键冲突而报错。更麻烦的是,如果源库的序列值已经跳到十万,而目标库从一重新开始,就会把历史数据覆盖掉。迁移完成后,要立刻检查所有自增字段的当前值,把序列跳到源库的对应位置。
日志和监控系统也要跟着迁移。数据库换了平台,原先基于源库的监控脚本、告警规则、慢查询分析全部要重新适配。我见过一个团队迁移后忘了调整备份策略,结果新库的日志文件疯长,把磁盘撑爆了。迁移完成后至少要观察一周,重点看慢查询的数量变化、锁等待频率、连接池的使用情况,这些指标能反映目标库的配置是否需要优化。
回到开头那个朋友的案例,后来我帮他重新规划了整个迁移流程,花了三天时间做预检,把所有可能出问题的点提前排查了一遍。正式迁移那天,整个切换过程用了不到四十分钟,业务无感完成。数据校验做了三遍,连每条订单的金额和状态都逐个核对过。他后来跟我说,早知道有这么多门道,当初就不该让团队盲目动手。
跨平台数据库迁移从来不是简单的搬运工活,而是一场需要精密策划的工程。把字符集、数据类型、存储对象、数据一致性、增量同步、权限体系、序列设置、监控运维这八个环节都提前想清楚,迁移才能做到心里有底。那些说零风险的人要么是运气好,要么是没遇到真正的挑战。但只要每个环节都按标准流程走一遍,风险就能控制在可接受的范围内。说到底,迁移这事,慢就是快,细就是稳。


