ora-600[25012]错误的本质原因是因为oracle在构造一致读的过程中发现undo block的rdba不对了,说到底还是因为块的损坏,解决方法就是往前递增全库的SCN,使oracle不产生一致读就可以了。当然,如果这个块已经坏的面目全非,那上述这种方法也不一定行。
我们来看一下我构造的这个例子:
SQL_testdb>drop table t1;
Table dropped.
SQL_testdb>create table t1(id number,name varchar2(10));
Table created.
SQL_testdb>insert into t1 values(1,'cuihua1');
1 row created.
SQL_testdb>insert into t1 values(2,'cuihua2');
1 row created.
SQL_testdb>commit;
Commit complete.
SQL_testdb>select * from t1;
ID NAME
---------- ----------
1 cuihua1
2 cuihua2
这么改:
1、 递增上述两条记录所在的itl的commit SCN;
2、 修改上述两条记录所在的itl的undo block的RDBA;
改完后ora-600[25012]如期而至:
SQL_testdb>select * from t1;
select * from t1
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [25012], [11], [971], [], [], [],
[], []
此时的解决方法很简单----就是递增全库的SCN不让oracle产生一致读就可以了。
递增完全库的SCN后可以看到ora-600[25012]已经不复存在:
SQL_testdb>select * from t1;
ID NAME
---------- ----------
1 cuihua1
2 cuihua2
我在"Oracle数据库恢复之如何解决ORA-600[25012]错误"这篇文章提到----ora-600[25012]错误的本质原因是因为oracle在构造一致读的过程中发现undo block的rdba不对了,说到底还是因为块的损坏,解决方法就是往前递增全库的SCN,使oracle不产生一致读就可以了。
我在写完上述这篇文章后得到了朋友的反馈说即便递增了全库的SCN,依然报错ora-600[25012]。
这是有可能的,因为如果oracle是因为相应的transaction未commit而被迫产生的一致读,那么这种情况下无论你怎样递增SCN都是没有效果的。此时我们的解决方法就是手工把这个transaction改成commit就好了。
我们来看一个实例:
SQL_testdb>drop table t1;
Table dropped.
SQL_testdb>create table t1(id number,name varchar2(10));
Table created.
SQL_testdb>insert into t1 values(1,'cuihua1');
1 row created.
SQL_testdb>insert into t1 values(2,'cuihua2');
1 row created.
SQL_testdb>commit;
Commit complete.
SQL_testdb>select * from t1;
ID NAME
---------- ----------
1 cuihua1
2 cuihua2
这么改:
1、 修改上述两条记录所对应的itl的flag,改为未commit;
2、 清掉上述两条记录所对应的itl中的commit SCN;
3、 修改上述两条记录所对应的ktuxe中的commit flag,由0x09改为0x10,注意这个commit flag是一定要改的,因为要避免oracle的延迟块清除;
4、 修改上述两条记录所在的itl的undo block的RDBA;
改完后相应block的ktbbh如下所示:
BBED> p ktbbh
struct ktbbh, 72 bytes @20
ub1 ktbbhtyp @20 0x01 (KDDBTDATA)
union ktbbhsid, 4 bytes @24
ub4 ktbbhsg1 @24 0x0000775d
ub4 ktbbhod1 @24 0x0000775d
struct ktbbhcsc, 8 bytes @28
ub4 kscnbas @28 0x80000904
ub2 kscnwrp @32 0x0001
b2 ktbbhict @36 2
ub1 ktbbhflg @38 0x03 (KTBFONFL)
ub1 ktbbhfsl @39 0x00
ub4 ktbbhfnx @40 0x00000000
struct ktbbhitl[0], 24 bytes @44
struct ktbitxid, 8 bytes @44
ub2 kxidusn @44 0x0011
ub2 kxidslt @46 0x001f
ub4 kxidsqn @48 0x00000167
struct ktbituba, 8 bytes @52
ub4 kubadba @52 0xf2c00484
ub2 kubaseq @56 0x003e
ub1 kubarec @58 0x23
ub2 ktbitflg @60 0x0002 (NONE)
union _ktbitun, 2 bytes @62
b2 _ktbitfsc @62 0
ub2 _ktbitwrp @62 0x0000
ub4 ktbitbas @64 0x00000000
struct ktbbhitl[1], 24 bytes @68
struct ktbitxid, 8 bytes @68
ub2 kxidusn @68 0x0000
ub2 kxidslt @70 0x0000
ub4 kxidsqn @72 0x00000000
struct ktbituba, 8 bytes @76
ub4 kubadba @76 0x00000000
ub2 kubaseq @80 0x0000
ub1 kubarec @82 0x00
ub2 ktbitflg @84 0x0000 (NONE)
union _ktbitun, 2 bytes @86
b2 _ktbitfsc @86 0
ub2 _ktbitwrp @86 0x0000
ub4 ktbitbas @88 0x00000000
执行完上述修改后ora-600[25012]如期而至:
SQL_testdb>select * from t1;
select * from t1
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [25012], [11], [971], [], [], [],
[], []
这个时候你会发现递增完全库的SCN后库已经起不来了,报错:
Mon Feb 28 14:32:14 2011
Errors in file /cadrasu01/app/oracle/admin/testdb/udump/testdb_ora_5955644.trc:
ORA-00600: internal error code, arguments: [4062], [17], [31], [16], [], [], [], []
Mon Feb 28 14:32:15 2011
Errors in file /cadrasu01/app/oracle/admin/testdb/udump/testdb_ora_5955644.trc:
ORA-00600: internal error code, arguments: [4062], [17], [31], [16], [], [], [], []
Mon Feb 28 14:32:15 2011
当我们解决完上述错误后会发现ora-600[25012]依然阴魂不散,即此时递增全库的SCN是没有效果的:
SQL_testdb>select * from t1;
select * from t1
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [25012], [11], [971], [], [], [],
[], []
这时候这么改:
1、 修改上述两条记录所对应的itl的flag,改为commit;
2、 伪造一个commit SCN,这个commit SCN只需要比相应的CSC大一点点就好;
3、 修改上述两条记录所对应的ktuxe中的commit flag,由0x10改为0x09;
改完后ora-600[25012]已经不复存在,上述两条记录又回来了:
SQL_testdb>select * from t1;
ID NAME
---------- ----------
1 cuihua1
2 cuihua2
Metalink 上的一些解释:
ORA-600 [25012] "Relative to Absolute File Number Conversion Error"
Note: For additional ORA-600 related information please read Note:146580.1
PURPOSE:
This article discusses the internal error "ORA-600 [25012]", what
it means and possible actions. The information here is only applicable
to the versions listed and is provided only for guidance.
ERROR:
ORA-600 [25012] [a] [b] [c]
VERSIONS:
versions 8.0 and above
DESCRIPTION:
We are trying to generate the absolute file number given a tablespace
number and relative file number and cannot find a matching file number
or the file number is zero.
ARGUMENTS:
Arg [a] Tablespace Number
Arg [b] Relative file number
Arg [c] Absolute file number (This arg is present is more recent releases)
FUNCTIONALITY:
KERNEL FILE MANAGEMENT TABLESPACE COMPONENT
IMPACT:
POSSIBLE PHYSICAL CORRUPTION
SUGGESTIONS:
The possibility of physical corruption exists.
Obtain the trace files and alert.log for this error and log a Service Request
with Oracle Support Services for diagnosis.
If the Arg [b] Relative file number returns 0 (zero), look for fake indexes
that can cause this error.
The following query list fake indexes :
select a.*,b.flags from dba_objects a, sys.ind$ b
where a.object_id = b.obj#
and bitand(b.flags,4096)=4096;复制