时间:2021-07-01 10:21:17 帮助过:5人阅读
Exp/Imp堪称是Oracle产品系列中的经典之作,以其简单易用在技术人员中广受欢迎。虽然从10g开始,Oracle开始逐步使用Data Pump来取
Exp/Imp堪称是Oracle产品系列中的经典之作,以其简单易用在技术人员中广受欢迎。虽然从10g开始,Oracle开始逐步使用Data Pump来取代其作为数据小规模逻辑备份还原工具,但是Exp/Imp对于普通开发人员还是比较有吸引力的。
从技术角度看,使用Exp/Imp的优点之一是客户端运行,使用人员不需要连入数据库服务器端,就可以方便的进行数据备份还原操作。试想DBA也不会轻易允许人登录敏感的Oracle服务器本机。
1、闲话Exp/Imp
Exp/Imp在实践领域经常遇到两个问题:一个是字符集转换,另一个是客户端/服务器版本协调。字符集转换根源于客户端软件的多样性,这要求每次使用Exp/Imp的时候,都需要显示的进行nls_lang环境变量的设置,只有这样才能保证正确的数据字符导出和导入。注意:很多开发人员喜欢使用PL/SQL Developer中的exp/imp工具,其实是变相的调用Oracle客户端可执行程序,这种方法没有办法设置nls_lang参数,,会遇到很多麻烦。
客户端/服务器版本协调就比较麻烦。使用exp/imp工具进行备份还原,其中涉及到四个软件的版本问题,即导出源数据库版本、导出exp客户端版本、导入目标数据库版本和导入imp客户端版本。高版本的导出客户端生成的dmp文件,在低版本导入客户端导入的时候,是不被兼容的。所以,无论是Oracle MOS官方,还是网络大侠牛人们的文章,都列出的复杂的矩阵表,来表示四个软件版本对应关系。
理论上,如果违反了软件兼容性原则,导出的dmp文件是不能成功导入的。需要重新规划导出操作,比较麻烦。本文记录一次笔者采用非常规策略解决兼容性问题的案例,留待“走投无路”的朋友“不时之需”。
2、导入IMP-00010错误
笔者源数据库是11gR2,需要将一个演示数据schema导入到另一台服务器上。由于时间比较久了,已经忘记目标数据库的版本号。笔者想当然以为应该是11gR2的Oracle,于是采用Exp工具导出。
出于简单习惯,笔者选择在服务器上执行exp命令,这样导出数据库和客户端均是11gR2。
等到导入数据的时候,出现了问题。
D:\DDD>imp \"/ as sysdba\" file=DDD_TESTING_20150901_exp.dmp fromuser=ddd_testing touser=ddd_testing
Import: Release 10.2.0.1.0 - Production on Wed Sep 2 22:36:31 2015
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Produc
tion
With the Partitioning, OLAP and Data Mining options
IMP-00010: not a valid export file, header failed verification
IMP-00000: Import terminated unsuccessfully
文件头不能识别,一般来说这种问题有两种可能:一种是文件出现坏块,在从FTP下载或者拷贝复制的过程中出现问题。另一种是版本兼容问题。
如果是第一种问题,理论上是没有其他办法,只能重新导出或者下载dmp文件。如果是兼容版本问题,需要检查一下目标数据库和导入客户端情况。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
导入目标是10g,而且客户端也是10gR2。这就出现了兼容性问题,低版本客户端“被认为”不能解析理解高版本客户端生成文件,所以才会报错拒绝导入。显示信息是文件头验证不通过。
3、非典型处理
笔者这时候基本没有别的选择。只能是回去重新用低版本客户端导出数据内容,或者选择Data Pump进行version调整的处理。但是在网络上,笔者找到了一种看似合理的处理方法。
Exp/Imp版本不兼容的现象,本质上是Oracle对于Dmp文件内容的限制。因为,Oracle担心低版本的Imp程序,不能理解高版本Dmp文件里面的内容和生成对象,所以才会有限制。笔者Dmp包里面只有数据表和一些普通索引对象,“高级”对象一个没有,这种限制其实没有意义。
那么,只需要将文件头稍做修改,让10gR2低版本客户端能够“认可”Dmp文件也就好了。根据这个思路,从网络上下载了notepad++编辑程序,直接打开Dmp文件。注意:这个过程其实有风险的,将近似二进制文件的Dmp以文本格式打开,要有一定心理准备。
打开文件后,可以看到文件头部信息,明显标注着Dmp文件版本11gR2内容。
将其修改为10gR2适应编号V10.02.01,之后保存。
保存后调用相同导入程序命令,导入正常开始。
D:\DDD>imp \"/ as sysdba\" file=DDD_TESTING_20150901_exp.dmp fromuser=dd_testing touser=dd_testing
Import: Release 10.2.0.1.0 - Production on Wed Sep 2 22:47:50 2015
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Produc
tion
With the Partitioning, OLAP and Data Mining options
Export file created by EXPORT:V10.02.01 via conventional path
import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
export client uses AL32UTF8 character set (possible charset conversion)
. importing UAT_TESTING's objects into UAT_TESTING
. . importing table "Aa" 0 rows imported
. . importing table "d" 0 rows imported
. . importing table "d" 134 rows imported
(篇幅原因,有省略……)
. . importing table "f" 0 rows imported
. . importing table "Xd" 0 rows imported
About to enable constraints...
Import terminated successfully without warnings.
导入动作简单的比较令人担心,只有启动约束命令。检查数据表和索引对象,确定导入成功。
SQL> select count(*) from dba_indexes where owner='DD_TESTING';
COUNT(*)
----------
1977
好在也是一个测试环境,有数据、约束和索引对象也就够用了,目标实现。
4、结论