love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

Phone:18180207355 提供专业Oracle/MySQL/PostgreSQL数据恢复、性能优化、迁移升级、紧急救援等服务

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

首先我们来看下朋友传我的alert log:

可以看到虽然该数据库能正常open,但是不停的报ora-00600错误,这里主要涉及到3个internal错误,分别为如下:

ORA-00600: internal error code, arguments: [kcoapl_blkchk]
ORA-00600: internal error code, arguments: [6006]
ORA-00600: 内部错误代码,参数: [12700]

我们先来看第一个错误:[kcoapl_blkchk],从该错误来看,可以判断是block存在问题,而又异常的block为:file 1 block 51720

我们可以看到open后smon进程在进行事务rollback的时候,回滚(10, 37) 事务失败了,主要是操作对象object 3.

这里可以简单的解释一下:(10,37) 中,标示回滚段编号,37标示slot编号。

我们可以确认,在Oracle 9i的环境中,object id=3 是i_obj#这个index。

我们从trace中搜索下,看下这个51720 的block有问题是什么问题 ?

从上面的错误可以看出,实际上这个Index block中有2个需要操作的ITL,其LCK都为1. 而Oracle认为这个block
这里需要操作的ITL应该只有1个。 这应该就是掉电导致没写入更改的原因。

换句话,要处理这个坏块,我们只需要将第3个ITL的信息改掉就行了。 通过bbed可以很容易的处理,修改状态,LCK等信息即可。

下面我继续看第2个ora-00600 [6006]错误。 我以前讲过多次,对于Oracle ora-00600错误,后面第一个错误号的范围
是4000~8000,其都跟Oracle事务有关系。 这里也不例外。 从这里的错误来看,Oracle smon进程在恢复事务(10, 38) on object 36
时出现异常,进而抛出该错误。

可以看到,9i中,object id=36 也是一个Index。 从这里的alert log来看,无法得到导致ora-00600 6006错误是什么block导致。

我们这里搜索smon trace即可,怎么搜索呢,很简单,搜索  seg/obj: 0x24即可,我们可以搜到如下内容:

根据这里的uba信息,我们还能搜索到回滚段的信息,如下;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

Leave a Reply

You must be logged in to post a comment.