前两天,一个朋友半夜给我打电话,声音里透着焦灼:他们公司要迁移一套 Oracle 数据库,几十张表、上千万条记录,业务不能停太久。他折腾了三天,导出导入来回折腾,结果始终没跑通。我听着他念叨那些报错信息——字符集不匹配、字段类型不兼容、索引重建失败——突然想起自己十年前第一次干这活时的情形。Oracle 数据库迁移看似是技术活,实际上是体力加脑力的综合游戏。你翻遍官方文档,背下所有命令,最后发现真正卡住你的,往往是文档里没有写的细节。

先说说最常见的坑:数据量大到一定程度,传统的 exp/imp 那套就扛不住了。我见过有人把一张 20 GB 的表用 exp 导出来,结果跑了整整一晚,第二天发现导出文件里有个字段因为特殊字符直接挂掉,前功尽弃。这时需要换工具,比如 Data Pump,速度快、支持并行,还能在导出时过滤数据。但 Data Pump 也不是万能药,它对网络要求高,远程导出时稍有不慎,丢包重传会把时间拉长两三倍。更麻烦的是,有些老系统用的 Oracle 版本低,目标库版本高,导出导入时的版本兼容性又是个坎儿。建议动手前先用一张测试表跑一遍全流程,看看实际耗时和报错,别一上来就全量搞。
数据迁移里最让人头疼的,往往是那些隐形的“脏数据”。比如某个字段只存了半个汉字,或者日期字段格式乱套,exp 导出时可能不报错,但 imp 导入时就炸了。我遇到过一个案例:一张订单表的备注字段,开发图省事,允许用户输入任意字符,结果里面夹杂了控制字符和换行符,导入时 Oracle 报 ORA-01461,提示字段长度超了。查了三天才发现,是这些不可见字符占用了字节数。解决办法很土:导出前先跑个 SQL 把非打印字符替换掉。别嫌麻烦,这一步能省后面十倍的时间。
索引和约束的迁移也是个技术活。很多人图省事,先导数据,再重建索引,结果发现重建索引的时间比导数据还长。尤其是大表上的复合索引,重建时要把整张表读一遍,磁盘 I/O 直接拉满,业务响应立马变慢。更烦的是,主键约束和外键约束的顺序搞错了,导入时报 ORA-02298,提示违反完整性约束。正确的顺序是先导数据,再建外键,不能乱。我习惯的做法是:导出时只导表结构和数据,索引和约束单独写脚本,等数据落地后再并行创建,这样既能控制资源占用,也方便回滚。
字符集不匹配是迁移里的老问题,几乎每隔几次就会碰上。比如源库是 AL32UTF8,目标库是 ZHS16GBK,汉字的编码长度不一样,导进去后要么乱码,要么截断。Oracle 官方建议统一使用 AL32UTF8,但很多老系统改不了,只能硬着头皮转。这时有两个选择:一是导出时指定字符集转换,但性能损耗大;二是在目标库建表时把字段长度放大,例如把 VARCHAR2(100) 改成 VARCHAR2(200),等数据迁完再调回去。我倾向于第二种,虽然多占点空间,但更稳定,不会中途出错。
业务连续性也是个绕不开的坎。很多公司要求迁移期间业务不停,或者只停几分钟。这听起来理想,实际上需要增量同步:先全量导出一次,把历史数据搬过去,再开启日志抓取增量变更,等增量追平后瞬间切换。Oracle 自带的 GoldenGate 能干这事,但配置复杂、许可证也贵。小公司玩不起,就用物化视图日志或触发器来补增量,效率低点,但成本可控。我见过一个团队,白天业务跑着,晚上偷偷做全量导出,凌晨两点切换,前后花了四天,硬是让业务感知不到。说白了,关键不是技术多牛,而是计划做得多细。
迁移完了,你以为就结束了?验收才是大头。数据量是否一致、业务功能是否正常、性能是否下降,都得测一遍。我有个习惯:迁移后先跑全表计数,和源库对一下行数,差一条都不行。然后随机抽几张大表,拉几条记录对比字段值,尤其是日期和数字精度,容易出幺蛾子。再让业务团队跑一遍核心流程——下单、查询、报表——每步都检查结果。有一次迁移后查询慢了十倍,排查半天发现是统计信息没更新,优化器选了糟糕的执行计划,跑一下 DBMS_STATS 就好了。这些坑,只有踩过才知道。
聊点实在的:别迷信工具,也别迷信文档。Oracle 迁移是工具的辅助,真正决定成败的是你对数据的理解。你知道哪些表是核心,哪些字段容易出问题,哪些业务场景对延迟敏感吗?这些信息不在技术文档里,而在业务人员的脑子里。所以动手前,花半天时间和业务聊清楚,比花三天读手册更有用。另外,永远留好回滚方案。我每次迁移都会保留源库的完整备份,确保万一出事能原地复原。这不是怂,是成年人的选择。


