近期,联通的增值网管系统,在执行EXPDP导出时,频频报ORA-39125、ORA-01555、ORA-06512,导致数据库的EXPDP备份被强制终止。
ORA-39125、ORA-01555、ORA-06512的具体信息如下:
Export: Release 10.2.0.4.0 - 64bit Production on 星期六, 17 1月, 2015 22:30:00
Copyright (c) 2003, 2007, Oracle. All rights reserved.
;;;
连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
启动 "SYSTEM"."SYS_EXPORT_SCHEMA_47": system/******** schemas=****** directory=backup_expdp dumpfile=expnms_201501171.dmp,exp_201501172.dmp,exp_201501173.dmp,exp_201501174.dmp filesize=40g exclude=statistics parallel=4 logfile=exp_20150117.log
正在使用 BLOCKS 方法进行估计...
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE_DATA
ORA-39125: 在 KUPW$WORKER.GET_TABLE_DATA_OBJECTS 中 Worker 发生意外的致命错误 (在调用 DBMS_METADATA.FETCH_XML_CLOB [TABLE_DATA:"*******"."UC_COMPLETENESS_KPI_CHECK":"P_20130101000000"] 时)
ORA-01555: 快照过旧: 回退段号 30 (名称为 "_SYSSMU30$") 过小
ORA-06512: 在 "SYS.DBMS_SYS_ERROR", line 105
ORA-06512: 在 "SYS.KUPW$WORKER", line 6313
----- PL/SQL Call Stack -----
object line object
handle number name
41ac01c40 15032 package body SYS.KUPW$WORKER
41ac01c40 6372 package body SYS.KUPW$WORKER
41ac01c40 9206 package body SYS.KUPW$WORKER
41ac01c40 1936 package body SYS.KUPW$WORKER
41ac01c40 6944 package body SYS.KUPW$WORKER
41ac01c40 1314 package body SYS.KUPW$WORKER
44180d828 2 anonymous block
作业 "SYSTEM"."SYS_EXPORT_SCHEMA_47" 因致命错误于 00:16:44 停止
与大家一样,看到ORA-01555,都想到是undo_retention太小了,看了下undo_retention大小如下:
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
于是,尝试调整undo_retention参数,使undo段中的数据保留的时间长一点,调整undo_retention为3600:
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 3600
undo_tablespace string UNDOTBS1
但是,经过观察发现,之前的EXPDP备份失败依然发生,并且失败的频率相比之前并没有任何变化。
通过观察数据库告警日志,发现该库EXPDP备份有时失败如上边提到的失败信息,有时候EXPDP会成功,如下:
. . 导出了 "*******"."STATUSNONPROPAGATE" 11.42 KB 81 行
已成功加载/卸载了主表 "SYSTEM"."SYS_EXPORT_SCHEMA_55"
******************************************************************************
SYSTEM.SYS_EXPORT_SCHEMA_55 的转储文件集为:
/opt/ZBNMSDB_BK/backup/exp_201501311.dmp
/opt/ZBNMSDB_BK/backup/exp_201501312.dmp
/opt/ZBNMSDB_BK/backup/exp_201501313.dmp
/opt/ZBNMSDB_BK/backup/exp_201501314.dmp
作业 "SYSTEM"."SYS_EXPORT_SCHEMA_55" 已于 02:21:41 成功完成
因此,该数据库的EXPDP备份失败是没有规律的,并且单独调整undo_retention是没有作用的;另外,他们备份也排除了统计信息导出,与统计信息也是没有关系的。
后来,仔细观察分析数据库报错信息,ORA-01555报错涉及的SQL语句如下:
SELECT /*+rule*/ SYS_XMLGEN(VALUE(KU$),
XMLFORMAT.createFormat2('TABLE_DATA_T', '7')), 0 , KU$.BASE_OBJ.NAME ,
KU$.BASE_OBJ.OWNER_NAME , 'TABLE' , to_char(KU$.BYTES_ALLOC) ,
to_char(KU$.ET_PARALLEL) , KU$.FGAC , KU$.NONSCOPED_REF , KU$.XMLSCHEMACOLS ,
KU$.NAME , KU$.NAME , 'TABLE_DATA' , KU$.PART_NAME , KU$.PARTTYPE ,
KU$.PROPERTY , KU$.REFPAR_LEVEL , KU$.SCHEMA_OBJ.OWNER_NAME , KU$.TS_NAME ,
KU$.TRIGFLAG , decode(KU$.SCHEMA_OBJ.TYPE_NUM, 2, decode(bitand(KU$.PROPERTY,
8192), 8192, 'NESTED TABLE', 'TABLE'), 19, 'PARTITION', 20, 'PARTITION',
'SUBPARTITION') , to_char(KU$.UNLOAD_METHOD) , KU$.XMLTYPE_FMTS FROM
SYS.KU$_TABLE_DATA_VIEW KU$ WHERE NOT BITAND(KU$.BASE_OBJ.FLAGS, 128)!=0 AND
NOT (BITAND (KU$.BASE_OBJ.FLAGS, 16)=16) AND NOT XML_OUTOFLINE='Y' AND
KU$.BASE_OBJ.OBJ_NUM IN (SELECT * FROM
TABLE(DBMS_METADATA.FETCH_OBJNUMS(100001)))
该SQL语句是获取方案分区表的分区信息的,由于查询表分区信息异常,消耗时间超过undo_retention限制而报ORA-01555。通过ORACLE官方metalink查询,具体的诱因是ORACLE的一个BUG 7362589。官方给出的建议是打补丁,但是数据库服务器操作系统是solaris、数据库版本是10.2.0.4的,官方没有相关可用的PATCH。另外,metalink未经发布的解决方法是:在expdp备份命令中加入版本兼容号version=10.2.0.1。
导致备份终止的是确定方案下的分区表UC_COMPLETENESS_KPI_CHECK,然后就尝试使用EXPDP备份加入版本兼容号version=10.2.0.1与不加版本兼容号做对比,单独备份导出失败的表,当加版本兼容号时,EXPDP竟然1分钟不到成功导出了;不加版本兼容号时,经过3次尝试,2次因ORA-01555退出而失败,1次备份成功却花费了20多分钟(但是所要备份的分区表有12个分区,一个分区才1M,正常情况下,备份20多分钟也是不正常的)。通过与系统维护人员协商,暂时尝试添加expdp备份版本兼容号来绕过oracle bug 7362589。
EXPDP备份修改前的命令
ORA-39125、ORA-01555、ORA-06512的具体信息如下:
Export: Release 10.2.0.4.0 - 64bit Production on 星期六, 17 1月, 2015 22:30:00
Copyright (c) 2003, 2007, Oracle. All rights reserved.
;;;
连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
启动 "SYSTEM"."SYS_EXPORT_SCHEMA_47": system/******** schemas=****** directory=backup_expdp dumpfile=expnms_201501171.dmp,exp_201501172.dmp,exp_201501173.dmp,exp_201501174.dmp filesize=40g exclude=statistics parallel=4 logfile=exp_20150117.log
正在使用 BLOCKS 方法进行估计...
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE_DATA
ORA-39125: 在 KUPW$WORKER.GET_TABLE_DATA_OBJECTS 中 Worker 发生意外的致命错误 (在调用 DBMS_METADATA.FETCH_XML_CLOB [TABLE_DATA:"*******"."UC_COMPLETENESS_KPI_CHECK":"P_20130101000000"] 时)
ORA-01555: 快照过旧: 回退段号 30 (名称为 "_SYSSMU30$") 过小
ORA-06512: 在 "SYS.DBMS_SYS_ERROR", line 105
ORA-06512: 在 "SYS.KUPW$WORKER", line 6313
----- PL/SQL Call Stack -----
object line object
handle number name
41ac01c40 15032 package body SYS.KUPW$WORKER
41ac01c40 6372 package body SYS.KUPW$WORKER
41ac01c40 9206 package body SYS.KUPW$WORKER
41ac01c40 1936 package body SYS.KUPW$WORKER
41ac01c40 6944 package body SYS.KUPW$WORKER
41ac01c40 1314 package body SYS.KUPW$WORKER
44180d828 2 anonymous block
作业 "SYSTEM"."SYS_EXPORT_SCHEMA_47" 因致命错误于 00:16:44 停止
与大家一样,看到ORA-01555,都想到是undo_retention太小了,看了下undo_retention大小如下:
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
于是,尝试调整undo_retention参数,使undo段中的数据保留的时间长一点,调整undo_retention为3600:
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 3600
undo_tablespace string UNDOTBS1
但是,经过观察发现,之前的EXPDP备份失败依然发生,并且失败的频率相比之前并没有任何变化。
通过观察数据库告警日志,发现该库EXPDP备份有时失败如上边提到的失败信息,有时候EXPDP会成功,如下:
. . 导出了 "*******"."STATUSNONPROPAGATE" 11.42 KB 81 行
已成功加载/卸载了主表 "SYSTEM"."SYS_EXPORT_SCHEMA_55"
******************************************************************************
SYSTEM.SYS_EXPORT_SCHEMA_55 的转储文件集为:
/opt/ZBNMSDB_BK/backup/exp_201501311.dmp
/opt/ZBNMSDB_BK/backup/exp_201501312.dmp
/opt/ZBNMSDB_BK/backup/exp_201501313.dmp
/opt/ZBNMSDB_BK/backup/exp_201501314.dmp
作业 "SYSTEM"."SYS_EXPORT_SCHEMA_55" 已于 02:21:41 成功完成
因此,该数据库的EXPDP备份失败是没有规律的,并且单独调整undo_retention是没有作用的;另外,他们备份也排除了统计信息导出,与统计信息也是没有关系的。
后来,仔细观察分析数据库报错信息,ORA-01555报错涉及的SQL语句如下:
SELECT /*+rule*/ SYS_XMLGEN(VALUE(KU$),
XMLFORMAT.createFormat2('TABLE_DATA_T', '7')), 0 , KU$.BASE_OBJ.NAME ,
KU$.BASE_OBJ.OWNER_NAME , 'TABLE' , to_char(KU$.BYTES_ALLOC) ,
to_char(KU$.ET_PARALLEL) , KU$.FGAC , KU$.NONSCOPED_REF , KU$.XMLSCHEMACOLS ,
KU$.NAME , KU$.NAME , 'TABLE_DATA' , KU$.PART_NAME , KU$.PARTTYPE ,
KU$.PROPERTY , KU$.REFPAR_LEVEL , KU$.SCHEMA_OBJ.OWNER_NAME , KU$.TS_NAME ,
KU$.TRIGFLAG , decode(KU$.SCHEMA_OBJ.TYPE_NUM, 2, decode(bitand(KU$.PROPERTY,
8192), 8192, 'NESTED TABLE', 'TABLE'), 19, 'PARTITION', 20, 'PARTITION',
'SUBPARTITION') , to_char(KU$.UNLOAD_METHOD) , KU$.XMLTYPE_FMTS FROM
SYS.KU$_TABLE_DATA_VIEW KU$ WHERE NOT BITAND(KU$.BASE_OBJ.FLAGS, 128)!=0 AND
NOT (BITAND (KU$.BASE_OBJ.FLAGS, 16)=16) AND NOT XML_OUTOFLINE='Y' AND
KU$.BASE_OBJ.OBJ_NUM IN (SELECT * FROM
TABLE(DBMS_METADATA.FETCH_OBJNUMS(100001)))
该SQL语句是获取方案分区表的分区信息的,由于查询表分区信息异常,消耗时间超过undo_retention限制而报ORA-01555。通过ORACLE官方metalink查询,具体的诱因是ORACLE的一个BUG 7362589。官方给出的建议是打补丁,但是数据库服务器操作系统是solaris、数据库版本是10.2.0.4的,官方没有相关可用的PATCH。另外,metalink未经发布的解决方法是:在expdp备份命令中加入版本兼容号version=10.2.0.1。
导致备份终止的是确定方案下的分区表UC_COMPLETENESS_KPI_CHECK,然后就尝试使用EXPDP备份加入版本兼容号version=10.2.0.1与不加版本兼容号做对比,单独备份导出失败的表,当加版本兼容号时,EXPDP竟然1分钟不到成功导出了;不加版本兼容号时,经过3次尝试,2次因ORA-01555退出而失败,1次备份成功却花费了20多分钟(但是所要备份的分区表有12个分区,一个分区才1M,正常情况下,备份20多分钟也是不正常的)。通过与系统维护人员协商,暂时尝试添加expdp备份版本兼容号来绕过oracle bug 7362589。
EXPDP备份修改前的命令
expdp system/Dnm%9001 schemas=****** directory=backup_expdp dumpfile=exp_20`date +%y%m%d`1.dmp,exp_20`date+%y%m%d`2.dmp,exp_20`date +%y%m%d`3.dmp,exp_20`date +%y%m%d`4.dmp filesize=40g exclude=statistics parallel=4 logfile=exp_20`date +%y%m%d`.log
EXPDP备份修改后的命令
expdp system/Dnm%9001 schemas=****** directory=backup_expdp dumpfile=exp_20`date +%y%m%d`1.dmp,exp_20`date+%y%m%d`2.dmp,expnms_20`date +%y%m%d`3.dmp,exp_20`date +%y%m%d`4.dmp filesize=40g VERSION=10.2.0.2 exclude=statistics parallel=4 logfile=exp_20`date +%y%m%d`.log
目前,该数据库备份恢复正常了。