love wife & love life —Roger的Oracle&MySQL技术博客

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

Wow,Index block have 169 ITLS ?

本站文章除注明转载外,均为本站原创: 转载自love wife & love life —Roger的Oracle&MySQL技术博客

本文链接地址: Wow,Index block have 169 ITLS ?

一个朋友的exadata环境遇到这个问题ora-00600错误,该错误其实很常见,比较有意思的事情是在后面。我们首先来看看alert log信息,如下:

如果没有遇到过这个错误的朋友,可能第一时间不知道是什么意思。标准的解释是这样的:The ora-600 [kdsgrp1] error is thrown when a fetch operation fails to find the expected row. The error is hit in memory and so may be a memory only error or an error that results from corruption on disk.
而产生这个错误的原因可能有如下几种:

我遇到的情况,通常来讲是跟Index有关系,我们先来分析下对应的trace文件。

只是知道执行这个SQL的时候触发了这个错误,从trace文件中我们直接搜索Plan Table可以定位到SQL的执行计划:

我们可以看到,该SQL运行时确实走Index,也是为什么会有这个问题了,如果要解决很简单,一般来讲rebuild Index即可。
下面我们分析下为什么会报这个错误? 需要分析另外一个trace,内容如下:

从上面的一句 file# 17 block# 77568 slot 2 not found,我们就比较清楚了。访问这个block的时候出现问题了。这里的slot其实是指的这个block的row 2. 从这里来看,我们发现这个block的第row=2 这行数据已经被delete了。
从这个block的itl来看,第1个ITL对应的事务已经commit了状态为U,但是还有个row的lock byte还没有被修改过来。根据UBA的地址,我们搜索trace,还可以看到这个block的redo相关信息:
这里根据前面的block中的XID:0x002d.005.0039d1ac 进行搜索:

这里的change# 2的opcode是5.1,是针对undo block的操作,换句话讲这里insert的记录就是上面的data block被delete数据的前镜像。接着下面的change# 的opcode是11.3 ,表示drop row,本质上就是指的前面的数据块的delete操作。
比较怪异的事情是,根据XID:  0x002d.005.0039d1ac 搜索,在数据块产生的redo下面搜索不到对应的index block的操作。
既然是这样,那我们来看下,删除的那条记录在Index block中的是否还存在。
既然是跟Index有关系,那么来看看Index Block的信息,由于Index column是第一列,因此我们直接看index block中是否还存在这行记录即可:c5 09 4e 16 24 5e ,搜索到如下的信息:

我们可以看到该键值还存在该index block中,也就是说Index的信息还没有被更新。(有可能是buffer cache的问题)

看到上面的信息,我也被吓了一跳!我靠,第一次见一个index block中居然高达169个ITL。理论上来讲这不是不可能,因为毕竟是主键Index,键值又是number,所占据的空间少。 不过即使是这样,还是把我吓尿了!根据dba地址确认,确实是属于查询报错的table的主键index!

我这里不得不怀疑是buffer cache corruption或者是lost writes了。这个问题不排除是bug导致。

总的来讲,这个问题处理是比较简单的。 另外,针对这个错误,我查询了一下,相关的bug也不少。
关于这个ora-00600 错误,大家可以参考如下2篇mos文章!
Detailed Steps for Troubleshooting ORA-00600 [kdsgrp1] (ID 1492150.1)

Causes and Solutions for ora-600 [kdsgrp1] (ID 1332252.1)

Leave a Reply

You must be logged in to post a comment.