【Oracle篇】使用impdp导入报错ORA-39001:ORA-39000:ORA-39142:incompatible version number xxx in dump file的问题解决

《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨

《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了解✌️

大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注

    如标题所示这篇文章是记录并分享一下使用数据泵导入时的报错,这个报错是博主在一年之前就遇到了,当时是研发人员需要将19c(19.0.0.0.0)中的某个生产用户数据导入到11g(11.2.0.4.0)时抛出的错误,属于降版本导入数据。

    其实这个需求挺奇葩的,明明已经是高版本19c了,19c不管是性能上还是新功能上都要比11g强,为啥还需要降版本导入到11g中呢?原因是因为目前其他项目上有用12c的,还有用19c等版本的,但当前需要协助导入数据的项目上还用的是11g,这个项目要拉其他项目上的数据来进行测试,如果不同版本上的数据都单独创建一个对应版本实例的话,使用dblink联调就比较麻烦,所以最好的办法就是统一将不同版本上的数据统一导入到一个版本中。大家都知道数据泵支持升版本的导入导出,也就是支持向上兼容;同样的Oracle的数据泵也支持降版本导入,极大方便了降版本的导入导出。

                   

问题描述:

在19c环境中导出某个生产用户的全部对象,执行如下expdp导出语句:

[oracle@oracle19c expdp]$ expdp \"/ as sysdba\" directory=EXPDP dumpfile=expdp_liudbywcs_%U.dmp logfile=expdp_liudbywcs.log schemas=liudbywcs parallel=2  COMPRESSION=all

                 

然后将19c中expdp导出的dmp文件,通过impdp导入到11g环境中:

[oracle@oracle11g expdp]$ impdp \"/ as sysdba\" directory=EXPDP dumpfile=expdp_liudbywcs_01.dmp,expdp_liudbywcs_02.dmp logfile=impdp_liudbywcs.log schemas=liudbywcs parallel=2 table_exists_action=append

                   

在11g环境中impdp导入时报错信息如下:

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-39142: incompatible version number 5.1 in dump file "/home/oracle/expdp/expdp_liudbywcs_01.dmp"

             

解决办法:

    只需要在导出expdp命令中加上 VERSION=11.2 (注意是expdp导出时加上,而不是impdp导入时加上哈),这里是因为需要降版本导入数据,目标是11g版本(11.2),所以VERSION指定的是11.2,如果需要将19c的数据导入到12c,那么VERSION指定就变成了12.2。对于目标实例低于源实例就需要用到此参数兼容低版本,如果目标实例高于源实例的话,一般不需要指定此参数,直接导入即可,关于升版本和降版本的导入导出在下面的《扩展(使用数据泵在不同Oracle数据库版本之间导出和导入)》我会详细说明。

                          

参数的用途:

    在使用 expdp(Data Pump Export)工具时,VERSION 参数用于指定导出操作中数据泵导出文件的版本号,会生成与指定版本兼容的dmp文件。它影响导出文件中数据的格式,可以用于在不同数据库版本之间迁移。

    VERSION 参数指定希望导出的数据库对象的版本。只有与指定版本兼容的数据库对象和属性才会被导出。可以使用 VERSION 参数创建一个与较早版本的 Oracle 数据库兼容的转储文件集。不能在 Oracle 数据库 10g 版本 1 (10.1) 之前的版本上使用数据泵导出,因为Oracle 10g时引入数据泵工具。数据泵导出仅适用于 Oracle 数据库 10g 版本 1 (10.1) 或更高版本。VERSION 参数的作用仅仅是确定导出对象的版本。

           

参数可以设置的值以及默认值:

VERSION=[COMPATIBLE | LATEST | version_string]    #官方文档中描述,此参数的默认值是COMPATIBLE
      
VERSION=COMPATIBLE(默认值):元数据的版本对应于在 COMPATIBLE 初始化参数中指定的数据库兼容性级别。注意:数据库的兼容性必须设置为 9.2 或更高版本。
VERSION=LATEST:元数据的版本和生成的 SQL DDL 对应于数据库的当前版本,而不管其兼容性级别。
VERSION=version_string:指定的数据库版本(例如,11.2.0)。在 Oracle 数据库 11g 中,此值不能低于 9.2。

                  

扩展(使用数据泵在不同Oracle数据库版本之间导出和导入):

以下部分知识点来源于 Oracle 公开可查的官方文档手册(Oracle 19c):Overview of Oracle Data Pump

    在升级场景中, Oracle Data Pump 迁移的目标版本高于源版本时,通常不需要显式指定 VERSION 参数。当目标版本高于源版本时,源数据库中的所有对象都与更高的目标版本兼容 。然而,有一个例外:当整个 Oracle 数据库 11g(版本 11.2.0.3 或更高版本)被导出,并准备导入到 Oracle 数据库 12c Release 1(版本 12.1.0.1)或更高版本时。此时,为了包含完整的 Oracle 数据库内部组件元数据,必须显式指定 VERSION=12 并且设置 FULL=YES。


    在降级的情况下,当 Oracle Data Pump 基于迁移的目标版本低于源版本时,应该将 VERSION 参数的值设置为与目标版本相同 。一个例外情况是当目标版本与源系统上 COMPATIBLE 初始化参数的值相同时,在这种情况下,无需指定 VERSION。但通常情况下,除非显式指定 VERSION 参数,否则 Oracle Data Pump 导入无法读取由比当前版本更新的 Oracle 数据库版本创建的转储文件集。


    在导出和导入不同版本的数据库时,注意事项如下:

  • 在 Oracle Data Pump 导出中,如果指定的数据库版本比当前数据库版本旧,则会创建一个可以导入到该较旧版本数据库的转储文件集。例如,如果正在运行 Oracle 数据库 19c,并且在导出时指定 VERSION=12.2,则创建的转储文件集可以导入到 Oracle 数据库 12c(版本 12.2)数据库中。仅在 Oracle 数据库 12c Release 1 (12.1.0.2) 及更高版本中有效的数据库权限(例如,表、视图、物化视图和同义词上的 READ 权限)不能导入到 Oracle 数据库 12c Release 1 (12.1.0.1) 或更早版本。如果尝试这样做,导入操作会报告错误,但会继续执行导入。 当导出到早于 Oracle 数据库 12c Release 2 (12.2.0.1) 的版本时,Oracle Data Pump 不会过滤掉超过 30 字节的对象名称。这些对象会被导出。在导入时,如果尝试创建一个名称超过 30 字节的对象,将会返回错误。
这里博主就遇到了一个问题,19c中的一个表的表名超过了30个字符,表名为LIU_ORACLEOLTP_YWCS_MH_FEE_LIST,那么通过expdp导出并指定VERSION=11.2时,导出报错如下:
ORA-39373: cannot export TABLE:"LIUDBYWCS"."LIU_ORACLEOLTP_YWCS_MH_FEE_LIST" to version 11.2 due to long identifiers

对于这个问题,是因为11g中一个表的表名最长只能30个字符,所以如果还需要继续导出的话,只能将表名修改一下,长度在30个字符以内就没有问题了
  • 如果指定的 Oracle 数据库版本低于当前的 Oracle 数据库版本,那么某些特性和数据类型可能不可用。例如,指定 VERSION=10.1 时,如果作业中同时指定了数据压缩,则会发生错误,因为 Oracle 数据库 10g Release 1 (10.1) 不支持数据压缩。另一个例子是:如果源 Oracle 数据库版本中的用户定义类型或 Oracle 提供的类型比目标 Oracle 数据库版本中的类型更新,那么该类型将无法加载,因为它与目标数据库中的任何版本的类型都不匹配。
  • Oracle Data Pump 导入始终可以读取由较旧版本的 Oracle 数据库创建的 Oracle Data Pump 转储文件集。
  • 当通过网络连接操作时,Oracle Data Pump 要求源和目标 Oracle 数据库版本之间的差距不得超过两个版本。例如,如果一个数据库是 Oracle 数据库 12c,则另一个 Oracle 数据库版本必须是 12c、11g 或 10g。Oracle Data Pump 只检查主版本号(例如 10g、11g、12c),而不检查具体的 Oracle 数据库版本号(例如 12.2、12.1、11.1、11.2、10.1 或 10.2)。
  • 将包含表统计信息的 Oracle 数据库 11g 转储文件导入到 Oracle 数据库 12c Release 1 (12.1) 或更高版本的 Oracle 数据库中,可能会导致 Oracle 错误 ORA-39346。此错误发生是因为 Oracle 数据库 11g 转储文件将表统计信息作为元数据存储,而 Oracle 数据库 12c Release 1 (12.1) 及更高版本要求将表统计信息作为表数据进行呈现。解决方法是在导入操作过程中忽略该错误。导入操作完成后,重新收集表统计信息。
  • 所有形式的 LONG 数据类型(LONG、LONG RAW、LONG VARCHAR、LONG VARRAW)自 Oracle8i Release 8.1.6 起被弃用。在后续版本中,LONG 数据类型作为向后兼容现有应用程序而提供。对于使用后续版本开发的新应用程序,Oracle 强烈建议使用 CLOB 和 NCLOB 数据类型来存储大量字符数据。

    Oracle中的数据泵是平时用的非常多的逻辑迁移工具,所以一些细节知识点还是需要按照官方文档认真学习的。通过系统学习和实践,我们能够更好地应对数据库管理的挑战,确保数据的高效与安全。

你可能感兴趣的:(Oracle专栏,oracle,数据库)