某客户Windows Oracle 9.2.0.1恢复案例

这是最近我们处理的某客户的数据恢复案例,客户环境为windows,Oracle 版本为9201。由于磁盘故障最后导致数据库无法打开。经过了解才知道,该客户在6月份就出故障了,期间找过多个厂家进行恢复,均未解决问题。最后客户通过很早之前的一个exp 备份恢复了业务,虽然目前业务已经正常,然而差了半年的数据,因此仍然需要进行恢复。
我们首先来看下数据库的告警日志信息,如下所示:

从上面的信息可以看出,客户的环境其实在5月份就出现过多次问题,alert log报了不少的错误,其中关于ORA-00600 [qerrmOFBu1]这个错误,根据mos 文档来看,极有可能是9201版本的bug。另外我们还可以看到存在ORA-00600 [729] 错误,该错误通常跟内存泄露有关,根据这一点也可以大致判断,客户的数据库环境内存可能不足。
事实证明,后面到现场了解情况发现,该数据库环境在虚拟机环境中,CPU和内存都比较少
我们继续来看最近一次的故障信息,如下:

我们可以发现,出问题之后,有工程师尝试进行了多次恢复,其中包括offline datafile的动作。最后多次打开数据库时都出现ORA-00600 [4000]错误,也正是卡在这个错误上,导致无法进行下一步。 由于这个错误,导致多个厂家都未能解决该问题。 我们首先来看下该错误所对应的trace 文件内容:

我们可以看到,在open 数据库时,Oracle 递归SQL执行失败,导致无法打开数据库。该错误本质上是因为在执行递归SQL的时候需要利用undo来构造一致性读,但是却发现undo存在损坏。由于是非归档环境,因此这里也就无法通过常规手段进行恢复。
该错误中,其中[6] 表示回滚段编号,也就是说访问出错的undo块属于第6号回滚段。
有人或许会说,如果使用隐含参数强制offline 第6号回滚段是否可以打开数据库呢? 实际上这里是不行的。
我们接着来看下该SQL访问的数据块为什么需要构造一致性读呢 ?

从上面信息可以看出,object id=18的对象上,确实存在一个block,事务状态为U,虽然事务已经commit,然而还存在一行锁定记录。Oracle的块清除分为2种:快速块清除和延迟块清除。很明显,这里属于快速块清除的情况,大多数情况之下的数据块清除都是快速清除,因为这样的效率比较高。
这里如果要把数据库open,那么其实通过bbed修改该block的ITL信息,标记事务为提交,同时修改lck等信息即可。
由于我通过DBV 检查主要的业务数据表空间文件时,发现存在上百个坏块,而且DBV检测到一定位置后就终止了,这可能是物理坏道的问题,如下:

同时考虑到数据量不大,不到30G,因此直接通过ODU恢复即可,因为system 检查发现只有1个坏块,数据字典是完好的。

备注:数据库的物理备份是必须的,否则一旦出现问题,将是灾难性的。