某客户 RAC 由于掉电导致系统崩溃的恢复过程
这里简单记录一下,此次国庆加班恢复的某客户的2套 Oracle RAC 数据库,整个恢复过程中,2套 rac 差不多,因此这里以其中一套数据库的恢复过程为例进行简单分析说明。数据库由于为非归档,由于掉电导致重启之后系统无法正常 open。
在正常 open 的过程中,报错如下错误:
对于该错误,网上的解决方法也很多,可惜都不管用。这种情况之下,往往都是需要强制打开数据库的,首先需要做一个不完全恢复,如下:
在进行相关操作之后,我备份了一下当前的控制文件信息,便于后面如果有问题,方便处理。强制 open 的过程中,发现报如下错误:
这个错误已经处理过多次了。同样,百度一下,会发现很多人都写过相关的文章,包括 Oracle mos 的文章解释也是说这是临时块的 scn 过大导致,通过 drop tempfile 即可绕过该问题。实际上,这种情况之下,根本不会起作用。
但是不管如何,这个问题很明显都是跟 block 的 scn 有关系。既然是跟 scn 有关系,那么处理就不难了,通过推进 scn 即可。
通过推进 scn 之后,再次 open resetlogs 成功打开数据库,可惜的是 alert log 报了一堆错误,如下所示:
这部分错误处理其实都不难。对于第一个 ora-00600 [4137] 错误,很明显这是跟 undo 有关系的,其中 (23,85) 中的23表现第23号回滚段;通过屏蔽第23号回滚段可以很容易解决该错误,当然,这会儿导致事务的不一致性,这是没办法的,已经 undo 异常,Oracle 已经没有办法进行正常的事务恢复了。
其次,对于第2个 ora-00600 [qertbFetchByRowID] 错误,处理也很简单,其大致意思是通过 rowid 访问获取数据有异常,很明显这是跟 index 有关系,通过重建 index 可以解决该问题,其次最后一个 [kdsgrp1] 错误就更常见了,通常也是 Index 的问题,重建即可。
看上去一切的恢复过程都很简单,很顺利,然而这里真正的难题,真正的问题才开始。也就是最后一个看似很简单的错误 ora-00600 [kdsgrp1] 错误,对我们产生了极大的困难。首先我们来看下产生该错误时涉及到那些对象:
我们可以发现,除开其他的非核心对象之后,这里还涉及到一个 obj#=18,也就是obj$ 这个核心的数据字典表。而该数据字典表上的几个 Index,i_obj1,i_obj2,i_obj3 都是 object_id 小于57的核心对象,这部分对象是属于 bootstrap$ 的核心数据字典对象。即是 Index 也无法通过 rebuild,38003 event 或在 upgrade 模式下进行重建。当然,这里也不是说完全无法去重建上述数据字典表,我后面有一篇文章会相信讲解如何去重建。在分析过程中,我发现其中的前面2个 Index都有问题,如下:
不过这里我们也要注意的时,虽然前面2个 index 都有问题,然而上述错误产生时涉及到的 index 并不是2个都用到了,其实只是用到了第一个 index 就报错 ora-00600 错误了。由于客户想通过 expdp schema 的方式去导出数据,然而发现执行时报错 ora-00600 [kdsgrp1],包括 exp 执行时也报该错误,不过 exp tables 的方式,不会报错;由于对象太多,将近50万个对象(包括表,index 以及其他)。很明显,只能通过用户级别的导出。那么也就在意味着我们必须修复这个错误才。通过 dump 相关的 block,我们发现错误是很奇怪的,如下:
对于上述这个 index 的错误,我是第一次遇见,跟老熊讨论了一下,他认为可能是index split 情况之下出现的。在远程时,我也用过 bbed 对前后将近10个 index block 进行了分析,通过比较 index 的链表,发现确实不匹配。对于这种情况之下,想通过 bbed 去修复 index,难度可想而知,因此果断放弃这种方式。最后无奈之下,只能通过处理数据字典表的方式来处理掉 i_obj1,i_obj2 这2个 index。最后再让客户进行 exp 用户级别的导出,只不过这个导出的时间比较漫长了。
----- The End
文章来源:【love wife & love life —Roger 的 Oracle 技术博客】
配图来源:https://www.securedatarecovery.ca/services/database-data-recovery
2015 Oracle 技术嘉年华10月31日前七折门票抢购进行中,点此注册参会!