问题发生场景:
使用expdp从oracle19c 导出表数据为11g版本时发生报错。
命令:
expdp user/pwd@pdb directory=dmp_dir dumfile=19c_2_11g.dmp logfile=xxx.log tables=test1 version=11.2.0.1
主要报错:
ORA-39126: Worker unexpected fatal error in KUPW$WORKER.FETCH_XML_OBJECTS
ORA-22813:ORA-22813: Operand Value Exceeds System Limits(元素值超出系统限制)
ORA-06512 at "SYS.DBMS_METADATA" :数字或值错误字符串缓冲区太小
问题分析过程
已知道高版本向低版本导出导入时,会因版本不同而产生问题,尤其是11g以后的版本向11g同步数据时。所以在导出数据时特意增加了version 参数。version=11.2.0.1
但是一旦加了这个参数后,导出就会报错。
第一次导出时虽然报错了,但是仍然导出了部分数据并生成了文件。
(没有校验数据的完整性,从结论来看,数据可能是完整的)
后续操作报同样的错误。
加了version=11.2.0.1 后导出数据时会提示 WARNING:从一个支持长标识符的版本导出到一个不支持长标识符的版本。
(这个警告其实是非常关键的)
但是检查了表名和字段名,以及varchar2的长度,均没发现问题。
最终解决办法
其一:
导出命令增加 EXCLUDE=STATISTICS
参数。
expdp user/pwd@pdb directory=dmp_dir dumfile=19c_2_11g.dmp logfile=xxx.log tables=test1 version=11.2.0.1 EXCLUDE=STATISTICS
导入时正常导入即可。
其二:
导出命令增加 CONTENT=DATA_ONLY
参数。
expdp user/pwd@pdb directory=dmp_dir dumfile=19c_2_11g.dmp logfile=xxx.log tables=test1 version=11.2.0.1 CONTENT=DATA_ONLY
由于只导出了数据,导入前需要在目标schema创建目标表,并在命令中指定导入到那张新表。不指定则会覆盖目标schema的同名表,无同名表则报错退出。
impdp user/pwd@pdb directory=dmp_dir dumfile=19c_2_11g.dmp logfile=xxx.log tables=test1 remap_schema=s1:s2 remap_table=test1:test2
这样就可以把s1.test1导入到目标库s2下的test2表。
原因:
确信:只能知道,问题不是出在表和数据本身,而是出在METADATA和STATISTICS(元数据、统计信息)。
导出数据时,默认会导出表数据和元数据。
猜想:所以,如果表空间或索引等其他元素的标识符超过30个字符,或值超出定义的长度就会报错。
也就是前边提到的
ORA-22813:ORA-22813: Operand Value Exceeds System Limits(元素值超出系统限制)