查看原文
其他

某客户 5TB RAC 恢复小记

2015-09-23 李真旭 云和恩墨

某客户的核心数据库存储问题导致数据库重启后无法正常启动,根据客户反馈最开始在启动数据库时报错控制文件 IO 错误,如下:




上述的问题本质上都跟控制文件有关系,替换掉损坏的控制文件就行。当替换掉控制文件之后,在 open 数据库时发现报如下错误:




该错误本质上是因为 redo 的问题,即有 redo log 损坏。通过在 RMAN 进行 recover,发现报如下类似错误:




上述过程大致是客户之前的处理过程。我在18点左右介入之后,进行了相关的操作。我最开始尝试在利用 RMAN 进行恢复,发现报错:




从上面的错误来看,初步可以判断 redo04a.log 文件已经损坏,而且是 block 1788672 的问题。为了验证该 block 是否损坏,我通过类似如下的 dump 命令进行 dump,发现报错:




由此判断,该 block 损坏无疑。 由于客户的需求是尽可能快的将数据库拉起来,因此对应 redo 损坏的情况之下。


通常只能进程不完全恢复并强制打开,这里我使用了如下的参数:




在 open resetlogs 之前,我已经将 redo 备份,resetlogs 打开时,发现数据库报错如下:




从日志来看,大致判断可能是_SYSSMU25$ 回滚段的问题,因此尝试先通过如下隐含参数屏蔽回滚段:




屏蔽回滚段之后,尝试打开数据库,发现错误依旧,通过10046 trace 跟踪,发现递归 SQL 在如下的 block 上执行失败:




通过 dump file 1 block 91,发现该 block 上第2个 ITL 确认存在一个活跃事务。原本计划直接 bbed 提交该事务,但是当我编译好 bbed 之后,查看发现该 block 为一个 cluster block.


对于 cluster block 的事务修改,相对复杂一些,我的博客有文章描述,大家可以参考,这里不多说。考虑到生产库使用 bbed 有一定的风险,我并没有使用 bbed。


接着使用 undo_management 参数启动数据库,然后强制 open 数据库,发现错误变成如下:




从错误来看,我们就可以知道,这应该是 SCN 的问题。如果要手工推进 SCN,那么 level 应该待遇3297*4才行,由于这里的 238091117/1024/1024/1024 小于1,因此推进 scn 时,level=3297*4+2 就差不多了。 这里我再次进行了10046 trace,发现了如下信息:




bscn: 0xce1.e379b05 将该 scn 进行转换,我们可以发现: 0xce1 为 3297,e379b05 为 238525189. 与上述报错信息一致。同时我发现这里使用了第2号回滚段,如下:




因此,尝试继续使用隐含参数屏蔽这第2号回滚段,并尝试打开数据库,但是错误依旧。看来还是需要调整 SCN 才行,如下:



首先我尝试了在会话级别设置:



发现 alter database open 失败,尝试使用*._minimum_giga_scn 参数,但是在启动的时候,提示说该参数不支持。从此判断,该环境可能是安装了比较新的 PSU,Oracle 将该参数废弃掉了,这么说前面的10015 event 根本就没起作用。 无奈只能通过 oradebug 手工修改 SCN 来启动数据库了,如下:



修改 SCN 之后,顺利打开了数据库,但是数据库很快就 crash 掉,如下是日志信息:




从上述日志信息来看,主要出现了如下几个错误:


ORA-00600 [6006],ORA-00600 [4137],ORA-00600 [kdsgrp1]


对于前面2个错误,很明显是 Oracle SMON 进程在进行利用回滚段进行事务 rollback 时失败导致,如下:


ORACLE Instance xxxx2 (pid = 22) – Error 600 encountered while recovering transaction (44, 26) on object 47098.
ORACLE Instance xxxx2 (pid = 22) – Error 600 encountered while recovering transaction (48, 25).


因此,不难看出,数据库中还有部分的回滚段存在活跃事务。


对于 ORA-00600 [kdsgrp1] 错误,通常是出现在 Index 上,即 Index 数据和表的数据不一致,一般来说可以通过重建解决。


其次,对于后面的 ORA-08102: index key not found, obj# 239, file 1, block 1674 (2) 错误,主要是 job 调用出现,因此我们可以暂时屏蔽 job 的调度。


对于 ORA-08102 错误,我的博客几年前也写过相关的文章,本质上也是 Index block 中的相关键值不存在导致。与其如此,最后我感觉将数据库的所有回滚段都屏蔽掉,并重建数据库 undo 表空间,如下是获取回滚段的命令:


strings system01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort -u


经过整理,发现该库存在大约2600个回滚段,我了个去,先不管这么多,重启实例后,重建 undo 表空间:



最后重启数据库实例,让客户将关键核心的配置表导出,先进行业务恢复,如果需要数据,直接从库中抽取。


这里要补充一点,该库约为5TB 多一点,虽然有备份,但是恢复时间太长,如果有个 dataguard 是多么的重要啊!


------The End


文章来源:【love wife & love life —Roger 的 Oracle 技术博客】

配图来源:http://www.security-faqs.com/usb-data-recovery-loss-prevention-tips.html


2015 Oracle 技术嘉年华10月7日前五折门票抢购进行中,长按上方图片识别二维码注册参会!



点击“阅读原文”查看原文章详情。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存