拿到一个DMP文件,就像拿到一个压缩过的世界。里面可能是一个项目的全部心血,也可能是公司跑了三年的业务数据。但很多人第一步就卡住了,对着这个二进制文件发愣,网上搜了一堆教程,结果不是版本对不上,就是权限报错,折腾半天还是导入不进去。这事儿我见得太多了,今天就把那些坑一个个给你指出来,让你拿到DMP文件就能稳稳当当导进数据库,不慌不忙。

先说最基础也最要命的一步:确认Oracle版本。DMP文件不是通用的,11g导出的文件,你拿19c去导入,大概率会报错,反过来也一样。别管网上那些“高版本兼容低版本”的说法,那是理论上的,实操中字符集、表空间,还有那些奇奇怪怪的包,都会让你头疼。我见过有人拿着一个10g的DMP,非要往12c里塞,结果报了一屏的ORA-错误码,灰溜溜地装了个10g的库才搞定。所以,动手之前,先问清楚这个DMP是从哪个版本导出的,或者用Notepad++打开文件看前几行,里面通常藏着版本信息。这一步省了,后面全是坑。
版本对上了,接下来就是权限问题。很多人用system账户去导入,结果还是报“权限不足”。这事儿不是system不行,而是你需要一个专门的目录权限。Oracle导入数据,默认要去读某个操作系统目录,你得先创建一个directory对象,然后把这个目录的读写权限授给要用的用户。具体命令不难,CREATE DIRECTORY dumpdir AS ‘/u01/backup’; 然后再GRANT READ, WRITE ON DIRECTORY dumpdir TO scott; 就这么两步。但就是这简单的两步,我见过至少十个人卡在这儿,因为他们压根儿没意识到Oracle还有这个机制,直接拿个路径就开始imp,报错报得莫名其妙。
再说说表空间的问题。DMP文件里记录了它原来在哪个表空间里,如果你的新库里没有同名的表空间,导入的时候就会报“表空间不存在”。解决办法有两个:一是提前建好同名的表空间,这个最稳妥;二是用impdp的REMAPTABLESPACE参数,把原来的表空间映射到现有的表空间上。比如原来的数据在USERS表空间里,你想放到DATATS,那就加上REMAPTABLESPACE=USERS:DATATS。这里有个细节,如果你用的是老的imp命令而不是impdp,那没有这个参数,只能老老实实提前建表空间。所以,我建议你直接用impdp,功能强得多,后面要说的几个坑也都能绕开。
字符集这个问题,最容易让人摸不着头脑。导入时如果报字符集不一致的警告,或者导入后中文全是问号,那基本就是这事儿。最理想的情况是源库和目标库的字符集完全一致,但现实中哪有那么巧。好在Oracle有个办法,可以在导入时指定字符集,但前提是DMP文件里的字符集信息是完整的。如果你的DMP文件是用exp导出的,那可以用expdp的VERSION参数配合NETWORKLINK来调整。但说实话,最省心的办法是在导入前先查一下DMP文件的字符集,然后用ALTER DATABASE CHARACTER SET来改目标库的字符集,虽然这操作要重启库,但一劳永逸。别偷懒,这个坑不填,后面数据全是乱的。
还有个大坑,就是表空间文件大小。很多DMP文件动辄几个G,导入的时候如果表空间是自动扩展的还好,要是你建表空间时没设AUTOEXTEND ON,那导入到一半就报“无法扩展表空间”的错。这事儿我踩过,当时导一个3G的文件,结果表空间最大才2G,卡在那儿动不了,只能停了重新建表空间再导。所以,建表空间的时候,直接把数据文件设大点,或者打开自动扩展,别省那点磁盘空间。另外,导入前看看目标库的磁盘空间够不够,别导到一半磁盘满了,那才是真的欲哭无泪。
再来说说导入时的并行度问题。很多人图快,在impdp命令里加上PARALLEL=4,结果发现CPU跑满,但导入速度反而没快多少,有时候还报资源冲突。这是因为并行导入对IO和内存的要求很高,如果你的服务器配置一般,反而会适得其反。我建议先不加PARALLEL,让它默认单进程跑,等摸清了数据量大小和服务器性能,再考虑要不要加。而且,并行导入时,如果DMP文件里某些对象之间有依赖关系,并行反而会导致锁等待,速度更慢。所以,别迷信并行,稳扎稳打才是正道。
还有一个细节,可能很多人没注意,就是导入时要不要先停掉应用。如果你的目标库正在跑业务,导入数据可能会和现有数据产生冲突,尤其是主键重复、外键约束这些。最稳妥的做法是,导入前把应用停掉,或者至少把相关的表锁住。但很多时候,业务不能停,那就得用impdp的TABLEEXISTS_ACTION参数,比如设为TRUNCATE或者REPLACE,但这两个都会动到现有数据,要慎重。我一般建议用SKIP,就是跳过已存在的表,只导入新增的表,或者用APPEND,把数据追加进去,但前提是你得确认没有主键冲突。
导入完了别急着欢呼,先做一遍验证。查一下每个表的数据行数,和源库对比一下,或者跑几个关键的查询看看结果对不对。我见过有人导入完就以为万事大吉,结果第二天业务方说数据对不上,一查发现少了几张表,原因是导入时漏了某个用户下的对象。所以,导入完一定要检查一下,可以用impdp的SQLFILE参数先生成一份导入脚本,看看里面包含了哪些对象,心里有个底。确认无误后,再让业务方去验证,这样才叫真正搞定。
DMP文件恢复这事儿,说难不难,说简单也不简单,全看你在细节上用了多少心思。版本、权限、表空间、字符集、并行度、验证,每一步都稳扎稳打,就能做到“轻松导入无压力”。下次再拿到一个DMP文件,别慌,按这个流程走一遍,你会发现,原来也就那么回事儿。


