具体参见:
http://t.askmaclean.com/thread-3790-1-1.html
http://www.itpub.net/thread-1839128-1-1.html
纯属自娱自乐,没有实际意义的,顺便说下我的发现和测试中的发现(虽然到现在为止数据库还没有open,我还会继续鼓捣他,毕竟还有些方法还没用上,O(∩_∩)O哈哈~。。。);
首先就是11.2太强大了,很多时候以往的错误都可以fixed,数据库可以open后,做很多跟损坏先关的check
1, 从11.2开始,控制文件自动备份完成的信息由m000完成,且他还完成很多其余工作,当然,只在别的进程触发的时候,他才会去工作
2,DBA_TABLESPACE和V$TABLESPACE的来源不同,一个来源于控制文件,一个来源于基表ts$
3,ts$和file$不能跳号
4,DBMS_HM很强大(Health Manager),他会定期检查数据库的很多东西,然后让m000进程写trace
。。。
主要的测试步骤已经不太都记得了,但是主要模拟步骤如下:
我的环境: db 11.2.0.3 OEL 5.8
1,创建2个表空间(其实1个也可以,几个都行,为了看得更加清晰),然后切换日志,然后在OS上讲包括UNDOTBS在内的这些数据文件(普通的数据文件和undo的数据文件就可以)
2,启动数据库的时候,你会发现,报错说文件丢失或者损坏,这时你offline drop掉这个报错的文件,数据库应该就可以打开,当然后台有m000生成的trace,HealthManager会不断的触发m000把所有其余随坏的信息都写入trace
3,想办法清理undo$中的问题回滚段
4,创建新的普通数据的表空间,例如“UNDTBS333”,但是设置UNDO_TABLESPACE=这个普通的表空间(scope=spfile),然后启动数据库————–这时我当时的第一个误操作
5,数据库报错,具体忘记了,怎么解决的也忘记了,印象中无非就是undo的隐含参数等等,然后创建正确的undo表空间(create undo tablespace …)给数据库使用
6,解决后,数据库可以正常open,delete from fs$ where name=‘你曾经误操作的那个普通数据表空间 UNDTBS333’,这么做是因为当时我没有仔细考虑风险,因此,手工清理了
其实如果全部都是手工做的话,也可以的,后面发现了需要手工清理什么,但是当时确实么有想太多,误操作了。。。
7,其实这样数据库也还是可以open的,没有太大问题,我用DBMS_HM.RUN_CHECK(‘Dictionary Integrity Check’, ‘lunar-ck-Dict’)检查,其实这时数据库只有undo$, ts$ 和file$数据不一致,没有影响其他数据对象(因为测试过程没有添加用户测试数据)
但是我脑子一热,进行了第二个误操作:重建控制文件
因为当时发现v$tablespace的内容显示不正确,但是dba_tablespaces显示是正确的。通过查询他们定义,发现v$tablespace的数据是源于x$kccts这个基表,也就是来源于控制文件的信息,而dba_tablespaces是基于ts$的
于是我就萌发了重建控制文件这个愚蠢的想法。。。。
8,重建控制文件的过程本身就报错了,你懂得。。。当然,后来可以屏蔽这个问题,忘记具体细节了,反正不难
9,再也没有拉起来数据库了
。。。。。
这个过程,通过10046,发现下面的语句报错,通过检查oracle二进制文件,可以很容易发现,这是因为数据库open的时候,会先把对file$进行插入操作,也就是根据bootstrap$找到file$的块,然后把全部内容插入这个表(当然状态为删除的会在接下来的步骤再做一个delete):
select blocks,NVL(ts#,-1),status$,NVL(relfile#,0),maxextend,inc, crscnwrp,crscnbas,NVL(spare1,0) from file$ where file#=:1
于是我想到了使用bbed修改file$,把我delete from fs$的那个表空间的数据文件修改为删除状态,经过测试,发现ts$和file$都不能跳号,比如这个file#是3,如果你把他的状态置为删除,那么重建控制文件的时候,后面多有的file#>3的都会在做一致性校验的时候,删除掉。。。
然后我只能还原了file$,然后就考虑将fs$中delete的记录恢复回来,但是这个我一直没找到好方法。。。
还有一个可以通过10046跟踪,找到报错语句,上面的问题很好解决,这个解决完了,是下面的错误:
select name,online$,contents$,undofile#,undoblock#,blocksize,dflmaxext,dflinit,dflincr,dflextpct,dflminext, dflminlen, owner#,scnwrp,scnbas, NVL(pitrscnwrp, 0), NVL(pitrscnbas, 0), dflogging, bitmapped, inc#, flags, plugged, NVL(spare1,0), NVL(spare2,0), affstrength from ts$ where ts#=:1
这个我一致没有绕过去,尝试修改oracle二进制文件应该是个方法,但是我用的不熟练,另外这个是最后一招,我总感觉现在还没有到非要这么做的时候。。。
于是就想办法跳过字典检查,使用gdb可以跳过数据字典检查:
(gdb) commands Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >set *0x60023388=0x0 >cont >end (gdb) cont Continuing. Breakpoint 1, 0x00000000022370e0 in kcfckdb () Program received signal SIGSEGV, Segmentation fault. 0x0000000002cbe19f in slaac_int () (gdb)
然后再次open resetlog数据库的时候:
Sat Nov 30 12:03:37 2013 ARC3 started with pid=21, OS id=29788 Undo initialization finished serial:0 start:127664534 end:127664564 diff:30 (0 seconds) Verifying file header compatibility for 11g tablespace encryption.. Errors in file /u01/app/oracle/diag/rdbms/bb/bb/trace/bb_ora_28960.trc: ORA-00604: error occurred at recursive SQL level 1 ORA-00376: file 1 cannot be read at this time ORA-01110: data file 1: '/stage/system01.dbf' Errors in file /u01/app/oracle/diag/rdbms/bb/bb/trace/bb_ora_28960.trc: ORA-00604: error occurred at recursive SQL level 1 ORA-00376: file 1 cannot be read at this time ORA-01110: data file 1: '/stage/system01.dbf' Error 604 happened during db open, shutting down database USER (ospid: 28960): terminating the instance due to error 604 Sat Nov 30 12:08:38 2013 USER (ospid: 29792): terminating the instance due to error 604 Termination issued to instance processes. Waiting for the processes to exit Sat Nov 30 12:08:48 2013 Instance termination failed to kill one or more processes
因此我需要知道一个断点,然后怎么设置那个断点,让数据库不做 “Verifying file header compatibility for 11g tablespace encryption”