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

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

11203 RAC(asm)恢复一例

本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL数据恢复博客

本文链接地址: 11203 RAC(asm)恢复一例

前天某客户的11203 rac(asm)出现掉电,导致数据库无法启动,注意数据库是归档模式。可见是多么倒霉。
据同事说开始是由于发redo和undo损坏导致无法启动,部分信息如下:

他做了一些recover database until cancel操作。甚至还使用了隐含参数,但是仍然无法open数据库,如下:
SQL> alter system set “_allow_resetlogs_corruption”=true scope=spfile ;
SQL> alter system set “_allow_error_simulation”=true scope=spfile ;
open数据库时报undo存坏块,如下:
11203 RAC(asm)恢复一例插图
可以看到,在使用隐含参数进行open都仍然报undo存在坏块。
本来我想进行不完全恢复,发现后面执行recover database using backup controlfile until cancel 居然
报ora-16433错误,很明显,同事之前做过resetlogs了,解决这个错误只能重建undo,本想通过如下方式
来重建controlfile的,发现居然不行:
oradebug setmypid
alter database backup controlfile to trace;
居然错误我记不住了。既然是报undo错误,那么首先的想法就是吧该undo坏块涉及的回滚段进行屏蔽。
通过10046 event可以定位到问题回滚段,但是,11g的回滚段格式发生了变化,仅仅是这样还不够的,如下是
10046 event的跟踪信息:

我们可以看到,在访问回滚段4的时候报错了,但是无法获得回滚段的时间戳。Oracle 11g中的回滚段名称的格式如下:
_SYSSMUx_时间戳.
实际上,回滚段的信息都存在undo$基表中,我们只需要获得该基表的数据即可。11g中该基表的数据在file 1 block 225block中。因此只需要dd该block,然后strings+grep就行了。
最后利用隐含参数_offline_rollback_segments=(_SYSSMUx$) 和_corrupted_rollback_segments=(_SYSSMUx$) 来屏蔽,讲数据库open。 open之后发现想drop问题回滚段居然报错,既然能open也就能够查询dba_rollback_segs试图了,最后
发现还有部分回滚段状态也是异常的,因此通过类似这一点 方法来drop 回滚段:

注意,这里如果不这样做的话,无法清理回滚段,你想切换undo 表空间也会报错的。
这个问题搞完后,最后发现一个数据文件的坏块,这个坏块折腾了我很长时间,非常奇怪:

可以看到,97号文件存在一个坏块,我dump了一下该block,发现比较怪:

大家可以看下这个坏块的type,居然是0x45,说这是一个lob extent header block。开始我还以为这个表存在lob字段,
最后desc看了下表结构,根本没有lob字段。可见这个block是写乱了。
大家知道处理坏块的方法无法就是10231 event,dbms_repair,以及dbms_rowid来处理。当时试了几种方法均不行。
其中10231 event和dbms_repair本质上差不多,都是标记坏块,跳过多块读。而dbms_rowid则是根据坏块获取rowid,然后
根据rowid来抢救数据。居然也不行,比较怪。
最后我干脆创建一个空间,分配到该文件,然后delete掉数据,然后dd一个空块,修改掉rdba和obj id,然后直接dd替换。
后记:后面让同事全库检查,还发现了20来个数据坏块,不过大多是Index,处理相对简单,我就不参与了。

Leave a Reply

You must be logged in to post a comment.