朋友的一个问题:9i的库open之后大量ora-00600错误(四)

2014-11-24 16:16:09 · 作者: · 浏览: 1
do: No rdba: 0x00000000 *----------------------------- index undo for leaf key operations KTB Redo op: 0x04 ver: 0x01 op: L itl: xid: 0x000a.02b.00021f77 uba: 0x008000c9.1036.4d flg: C--- lkc: 0 scn: 0x0000.0a2c96d4 Dump kdilk : itl=2, kdxlkflg=0x1 sdc=77869776 indexid=0x4000d9 block=0x0040cf0f purge leaf row key :( 6): 05 c4 02 0d 15 16 。。。。

从上面的信息回滚段头的dump内容可以看出,该回滚段涉及2个活动事务,事务槽编号为0×25,0×26 即:37,38。 这和前面的错误是符合的.

我们可以清楚的看到,这里的0×26的这个事务涉及的blockdump来看,LCK都是0,看上去没啥异常,为什么这个事务会有异常呢 ?

在Oracle中,smon 进行回滚操作,是以事务为单位进行的。对于undo而言,涉及到一个undo chain的结构。

关于Oracle undo chain,在我的Oracle特殊恢复课程里面讲过。

我们可以看出,0×26这个事务应该从0×13 这个record开始回滚,到0×12这个record这里就结束。从信息来看似乎也没有什么不对的地方?

那为什么这个事务会rollback失败呢 ?
大家注意看undo record 0×13,0×12的XID 信息:xid: 0x000a.02b.00021f77

关于XID的结构,在我的Oracle特殊恢复课程里面也有讲解。第2部分其实表是ktuxe结构中的index编号。第3部分标示ktuxe中的wrap#。

从这里看来,是Oracle没来得及更改block中的信息。因此这里我怀疑是undo有点问题,正常情况下,undo block中的xid的信息这里

应该会更改为0x21f84,同时ktuxe中的事务状态信息会更改,cflags的值也会更改为0×00. 这样才标示一个事务commit结束。
最后我们来看下ORA-00600: 内部错误代码,参数: [12700]这个错误。管哟12700错误,Oracle mos有一篇文档:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ERROR: ORA-600 [12700] [a] [b] [c] VERSIONS: versions 6.0 to 9.2 DESCRIPTION: Oracle is trying to access a row using its ROWID, which has been obtained from an index. in Oracle 8.x and 9.x, it is ORA-600 [12700][a][b][c] , where Arg [a] dataobj# from sys.obj$ Arg [b] relative dba of the data block Arg [c] slot number of the row in the data block

根据上面的解释来看下这个错误:
ORA-00600: 内部错误代码,参数: [12700], [18], [4246724], [2], [], [], [], []

我们可以看出,问题出在obj#=18 这个对象上的block(dba地址4246724)上的第2个ITL。

可以通过dbms包可以将该dba地址进行转换,我们来看下是什么block :

1 2 3 4 5 6 SQL> select dbms_utility.data_block_address_file(4246724) file_id, 2 dbms_utility.data_block_address_block(4246724) block_id from dual; FILE_ID BLOCK_ID ---------- ---------- 1 52420

我们搜索下trace,来看下该block的dump信息:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 BH (0x6B7EAD88) file#: 1 rdba: 0x0040ccc4 (1/52420) class 1 ba: 0x6B47C000 set: 3 dbwrid: 0 obj: 18 objn: 18 hash: [67e8aa14,6bfee6d0] lru: [6b7edcd0,6b7ee36c] LRU flags: hot_buffer ckptq: [NULL] fileq: [NULL] use: [67e3d1d0,67e3d1d0] wait: [NULL] st: XCURRENT md: SHR rsop: 0x00000000 tch: 6 LRBA: [0x0.0.0] HSCN: [0xffff.ffffffff] HSUB: [255] RRBA: [0x0.0.0] buffer tsn: 0 rdba: 0x0040ccc4 (1/52420) scn: 0x0000.0a2ca3e0 seq: 0x01 flg: 0x04 tail: 0xa3e00601 frmt: 0x02 chkval: 0x2d3b type: 0x06=trans data Block header dump: 0x0040ccc4 Object id on Block Y seg/obj: 0x12 csc: 0x00.a2c9c1d itc: 2 flg: O typ: 1 - DATA fsl: 0 fnx: 0x40ccc2 ver: 0x01 Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x0002.011.00021f3d 0x00800ace.1020.0a C--- 0 scn 0x0000.0a2c9c13 0x02 0x0004.01a.00021f16 0x00800964.104c.3b --U- 2 fsc 0x0096.0a2c9c22 data_block_dump,data header at 0x6b47c05c =============== tsiz: 0x1fa0 hsiz: 0x96 pbl: 0x6b47c05c bdba: 0x0040ccc4 76543210 flag=-------- ntab=1 nrow=66 frre=0 fsbo=0x96 fseo=0x6a2 avsp=0x1455 tosp=0x14ef 0xe:pti[0] nrow=66 offs=0 。。。。。

从dump来看,该block的第2个ITL 存在事务操作,锁定了2行记录. 这跟alert log的抛出的错误是符合的。

针对该错误,是Oracle读取时发现index和table的数据不一致导致的。针对表obj$,我们可以来看下报错的sql的执行计划:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Plan Table -------- ------------------------------------------------------------------------------------------------------------------------- | Operation | Name | Rows | Bytes | Cost | TQ |IN-OUT| PQ Distrib |Pstart| Pstop | ------------------------------------------------------------------------------------------------------------------------- | SELECT STATEMENT | | 0 | 0 | 0 | | | | | | | SORT ORDER BY | | 0 | 0 | 0 | | | | | | | FILTER | | 0 | 0 | 0 | | | | | | | NESTED LOOPS | | 0 | 0 | 0 | | | | | | | NESTED LOOPS OUTER | | 0 | 0 | 0 | | | | | | | NESTED LOOPS | | 0 | 0 | 0 | | | | | | | NESTED LOOPS | | 0 | 0 | 0 | | | | | | | TABLE ACCESS FULL | USER$ | 0 | 0 | 0 | | | | | | | TABLE ACCESS BY INDEX R | OBJ$ | 0 | 0 | 0 | | | | | | | INDEX RANGE SCAN | I_OBJ2 | 0 | 0 | 0 | | | | | | | TABLE ACCESS BY INDEX RO | SYN$ | 0 | 0 | 0 | | | | | | | INDEX UNIQUE SCAN | I_SYN1 | 0 | 0 | 0 | | | | | | | TABLE ACCESS BY INDEX ROW | USER$ | 0 | 0 | 0 | | | | | | | INDEX UNIQUE SCAN | I_USER1 | 0 | 0 | 0 | | | | | | | TABLE ACCESS CLUSTER | USER$ | 0 | 0 | 0 | | | | | | | INDEX UNIQUE SCAN | I_USER# | 0 | 0 | 0 | | | | | | | TABLE ACCESS BY INDEX ROWID | OBJ$ | 0 | 0 | 0 | | | | | | | INDEX RANGE SCAN | I_OBJ2 | 0 | 0 | 0 | | | | | | -------------------------------------------------------------------------------------------------------------------------

很明显可以看出,这里对于obj$表的访问使用了2个Index,i_obj2. 看来问题就出在该对象之上。

这里其实可以用过如下命令来判断具体是什么行的信息不匹配导致:

1 analyze table obj$ validate structure cascade ;

定位到问题hang之后,由于这是bootstrap$的对象,因此无法通过在数据库open的时候进行rebuild 来进行解决。

可以通过如下2种方式来解决该问题:

1) bbed modify index block
2) 通过bbed 将i_obj2这个index drop掉。