非规范处理IMP-00010错误一例

从技术角度看,使用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、结论

笔者的处理方法,其实是有很大风险和隐患的。放在平时测试环境中,一时选择失误的补救策略还是可以接受的。如果是正式环境,一定要根据规范进行操作,通过实现测试预判问题风险,设计解决方案,务必保证所有对象能够顺利导入。

另外,笔者这种方法其实是违背Oracle原则的,如果笔者dmp文件中存在一些新特性对象,或者版本差异很大,也不能保证导入操作的顺利。

记录下来,权作一家之言~

猜你喜欢

转载自www.linuxidc.com/Linux/2015-09/123014.htm