Author: Rainny
Date: 2010-2-23
虎年刚过,就接手了一个非常困难的ORACLE数据库恢复的CASE。
数据库经历了不正常断电,STARTUP ORACLE时报:
ORA-01172: recovery of thread 1 stuck at block 3859656 of file 6
ORA-01151: use media recovery to recover block, restore backup if needed
查看ALERTLOG,发现前面已经有几个错误了:
ORA-00600: internal error code, arguments: [kdxlin:psno out of range], [], [], [], [], [], [], []
Hex dump of (file 3, block 30968) in trace file /data/app/oracle/admin/ora33/bdump/ora33_p003_6219.trc
Corrupt block relative dba: 0x00c078f8 (file 3, block 30968)
Fractured block found during crash/instance recovery
Data in bad block:
type: 6 format: 2 rdba: 0x00c078f8
last change scn: 0x0000.92db87df seq: 0x1 flg: 0x06
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x4a500601
check value in block header: 0x60f
computed block checksum: 0x43d0
Reread of rdba: 0x00c078f8 (file 3, block 30968) found same corrupted data
看这个情况是发生了块损坏,根据以往的经验,不正常断电的情况下,redo和undo都可能发生损坏,导致数据不一致,ORACLE无法自动完成实例恢复,导致数据库打不开。
问了客户有没有备份可用,回答是没有备份。只有逻辑备份,且是年前的备份。客户希望尽快恢复DB的正常运行。这个DB大概有将近100G,由于客户想要尽快恢复,没有时间对现场进行备份,所以在无路可退的情况下进行了下列操作,结果错误百出,中间不断冒出新问题,其中细节在此不详述,事后我给自己添加了一条原则:在没有做现场备份的情况下不要给客户做此类恢复。因为,万一恢复不成功,我没有回退的余地,很难和客户解释和交代。懂得技术的人可能会理解我,但要是碰到不懂的客户,可能以为是我搞砸了。总之,简而言之,数据库备份很重要,在没有备份的情况下恢复ORACLE数据库,压力很大。粗略的描述一下过程,以记之:
用RMAN尝试对数据库进行恢复,发布RECOVER DATABASE命令(虽然没有备份)碰碰运气,看现有的REDO能否完成数据库的恢复,结果报错,提示要RESTORE备份。查看ALERTLOG,发现是REDO有问题,由于没有备份可RESTORE,尝试打开隐含参数:_allow_resetlogs_corruption,再次open数据库,还是不成。
alter session set events '10015 trace name adjust_scn level 1增加SCN值,再次open db,情况发生了一些改变,这次报了ORA-00600的2662错误,这是在打开隐含参数:_allow_resetlogs_corruption后通常都会遇到的错误,看到这个错误,我心里稍微有数,以为再搞几下就可以顺利打开DB了。然情况比我想象的复杂。如果ORA-00600的2662错误中第三个参数和第五个参数差别很小,那么就可以通过多次打开关闭数据库实例的方式来增加SCN的值。
我重试了3次OPEN,都不能成功打开DB,再次尝试增加SCN:
ALTER SESSION SET EVENTS '10015 TRACE NAME ADJUST_SCN LEVEL 10';
对于10g,缺省情况_ALLOW_ERROR_SIMULATION是FALSE,这会阻止ADJUST_SCN,所以要做ADJUST_SCN必须设置这个隐含参数为TRUE,这是使用EVENTS调整SCN的前提条件。
反复RESTART DB,都没能成功打开,搞了几次,又出现新的错误:
ORA-00600: internal error code, arguments: [4193], [4306], [4309], [], [], [], [], []
看来UNDO也出现了问题。启用另外一个隐含参数:_CORRUPTED_ROLLBACK_SEGMENTS
将所有的UNDO管理方式改为手工,并加入所有的UNDO SEGMENTS(可以alertlog提到的.trc文件中查出),下面是init参数:
_allow_resetlogs_corruption=TRUE
undo_management='MANUAL'
_corrupted_rollback_segments=(rbs _SYSSMU1$,rbs _SYSSMU2$,中间省略rbs _SYSSMU10$)
我以为这次能够顺利打开DB,结果,非常奇怪,数据库又报出最初出现的错误,这回换成是SYSTEM文件了:
ORA-00604: error occurred at recursive SQL level 1
ORA-01578: ORACLE data block corrupted (file # 1, block # 60616)
ORA-01110: data file 1: '/data/oradata/ora33/system01.dbf'
中间再次尝试了几次假的不完全恢复,并创建了一个新的UNDO表空间,在INIT文件中指定:
*.undo_tablespace=undotbs2
并以PFILE重新创建SPFILE:
SQL> create spfile from pfile='/home/oracle/initora33.ora';
File created.
反复以RESETLOGS打开DB,直到最后看到下列信息:
SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01248: file 30 was created in the future of incomplete recovery
ORA-01110: data file 30: '/data/oradata/ora33/undotbs2.dbf'
经过几次重启,最后,终于成功的OPEN ORACLE:
SQL> alter database open resetlogs;
Database altered.
到此,我的眼睛已经将近2个小时没有离开电脑屏幕了。水也忘了喝一口,我站起身,通知客户EXP数据库,后面用DBCA重建DB,并导入数据的过程轻车熟路,非常顺利,到下午下班之前,数据库顺利恢复运行。
[@more@]来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/684234/viewspace-1031413/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/684234/viewspace-1031413/