不管怎样强调,我们还是经常遇到非归档、无备份的用户数据库,这样的数据库一旦当前重做日志文件损坏,那么Oracle是不允许数据库打开的。这样的限制是因为重做日志损坏,意味着会丢失提交成功的数据,Oracle的数据文件中也可能存在不一致的数据,而不一致问题是数据库无法打开的根本原因。
这样的后果是极其严重的,用户期望能够忽略一致性问题,强制打开数据库,以挽回数据损失。在正常情况下,这样的期望是无法实现的。
但是Oracle存在一个内部参数可以针对类似的情况进行恢复尝试,这个参数就是_allow_resetlogs_corruption,我们可以从数据库内部获得这个参数的意义描述:
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
2 FROM SYS.x$ksppi x, SYS.x$ksppcv y
3 WHERE x.inst_id = USERENV ('Instance')
4 AND y.inst_id = USERENV ('Instance')
5 AND x.indx = y.indx
6 AND x.ksppinm LIKE '%&par%'
7 /
Enter value for par: allow_resetlogs
NAME VALUE DESCRIB
--------------------------- ------- ------------------------------------------------
_allow_resetlogs_corruption FALSE allow resetlogs even if it will cause corruption
这个参数的含义就是允许在数据库不一致的情况下强制重置日志,设置这个参数可以使得Oracle在启动过程中强制跳过一系列的一致性检测,强制打开数据库。但是注意,在使用这个参数之前,一定要记得备份当前的数据库环境,保留现场,以便恢复失败后仍然能够退回到最初的状态。
下面通过一个案例来讨论这个参数的用法。以下数据库在启动过程中报告日志文件损坏:
SQL> startup;
ORACLE instance started.
<…ignore SGA info here…>
Database mounted.
ORA-00354: corrupt redo log block header
ORA-00353: log corruption near block 3 change 897612314 time 10/19/2005 14:19:34
ORA-00312: online log 3 thread 1: '/opt/oracle/oradata/conner/redo03.log'
通过v$log视图可以确认,损坏的是Active的日志文件,Active的日志文件在实例恢复时是必须的,损坏了Active的日志和损坏Current的日志情况相同:
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
------ ------- ---------- --------- ------- --- -------- ------------- ---------
1 1 159 10485760 1 NO INACTIVE 897592312 19-OCT-05
2 1 158 10485760 1 NO INACTIVE 897572310 19-OCT-05
3 1 160 10485760 1 NO ACTIVE 897612314 19-OCT-05
4 1 161 1048576 1 NO CURRENT 897612440 19-OCT-05
如果没有备份,只好尝试使用隐含参数_allow_resetlogs_corruption强制启动数据库:
SQL> alter system set "_allow_resetlogs_corruption"=true scope=spfile;
System altered.
SQL> shutdown immediate;
ORA-01109: database not open
Database dismounted.
ORACLE instance shut down.
重新启动数据库,执行recover操作尝试(不执行不完全恢复操作,Oracle是不允许Resetlogs打开数据库的),在提示归档日志时,直接输入Cancel取消恢复:
SQL> startup mount;
ORACLE instance started.
Database mounted.
SQL> recover database using backup controlfile until cancel;
ORA-00279: change 897612315 generated at 10/19/2005 16:54:18 needed for thread 1
ORA-00289: suggestion : /opt/oracle/oradata/conner/archive/1_160.dbf
ORA-00280: change 897612315 for thread 1 is in sequence #160
Specify log: {=suggested | filename | AUTO | CANCEL}
cancel
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: '/opt/oracle/oradata/conner/system01.dbf'
ORA-01112: media recovery not started
然后可以强制resetlogs打开数据库,此数据库成功打开,重起能够正常打开:
SQL> alter database open resetlogs;
Database altered.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Database mounted.
Database opened.
这是比较幸运的情况,数据库可以成功Open,如果不幸可能会遇到一系列的ORA-600错误(最常见的是2662错误)此时就需要使用多种手段继续进行调整恢复。
如果注意观察alert日志,可能会发现类似以下日志:
Fri Jun 10 16:30:25 2005
alter database open resetlogs
Fri Jun 10 16:30:25 2005
RESETLOGS is being done without consistancy checks. This may result
in a corrupted database. The database should be recreated.
RESETLOGS after incomplete recovery UNTIL CHANGE 240677200
Resetting resetlogs activation ID 3171937922 (0xbd0fee82)
Oracle告诉我们,强制resetlogs跳过了一致性检查,可能导致数据库损坏,数据库应当重建。不一致恢复最后恢复到的Change号是240677200。通常使用此方法Open数据库之后,应该立即通过导出、导入重建数据库。