从SCN角度 :理解 重建控制文件(通过trace)中的 reset log 和 no retset log

来源:互联网 发布:网络一会好一会断 编辑:程序博客网 时间:2024/06/05 17:01

第一部分:

介绍下 重建控制文件后,有两种方式打开数据库: resetlog 和 noresetlog:


alter database open resetlog 
指定RESETLOGS将重设当前LOG sequence number为1,抛弃所有日志信息。

以下条件需要使用resetlog(说白了,如果你的redo不完整那就resetlog -如果完整,仅仅是控制文件丢了,那就noresetlog,这样不会丢数据):
1)在不完全恢复(介质恢复)
2)使用备份控制文件


举个例子:

重建控制文件适用于所有控制文件都丢失的情况下,流程分为以下几步:

1.执行脚本,重建控制文件(CREATE CONTROLFILE REUSE DATABASE "HOEGH"RESETLOGS NOARCHIVELOG......)
2.执行介质恢复RECOVER DATABASE USING BACKUP CONTROLFILE / RECOVER DATABASE
3.打开数据库
4.添加临时表空间

看看网上这个例子:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3635829

我就这位仁兄的实验简单说说原理吧 :



控制文件的损坏:

法一。使用新的控制文件覆盖旧的控制文件:


法二.a。日志完好,控制文件重建:
1. 插入一个新数据,以看数据是否会受影响
SYS@bj> drop table scott.t3;
drop table scott.t3
                 *
ERROR at line 1:
ORA-00942: table or view does not exist


SYS@bj> create table scott.t3 as select * from scott.salgrade;

Table created.

SYS@bj> select count(*) from scott.t3;

  COUNT(*)
----------
         5

2. 破坏控制文件

SYS@bj> select 'host echo 111 > ' || name from v$controlfile;

'HOSTECHO111>'||NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
host echo 111 > /u01/app/oracle/oradata/beijing/control01.ctl
host echo 111 > /u01/app/oracle/oradata/beijing/control02.ctl

执行破坏,破坏后,切换日志:
SYS@bj> alter system switch logfile;
alter system switch logfile
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel

报错,不在连接到通信终止。:因为控制文件丢了,没法将scn等变化写入到控制文件了。

Oracle实例崩溃
SYS@bj> ho ps -ef | grep ora_
oracle    5764  5465  0 20:37 pts/8    00:00:00 /bin/bash -c ps -ef | grep ora_
oracle    5766  5764  0 20:37 pts/8    00:00:00 grep ora_

3.显示连接到空闲实例:
SYS@bj> conn / as sysdba
Connected to an idle instance.

SYS@bj> startup 
ORACLE instance started.

Total System Global Area  293601280 bytes
Fixed Size                  1219016 bytes
Variable Size             234882616 bytes
Database Buffers           50331648 bytes
Redo Buffers                7168000 bytes
ORA-00205: error in identifying control file, check alert log for more info
 
alert log中有如下一段描述:
ALTER DATABASE   MOUNT
Mon Mar 14 20:38:54 2011
ORA-00202: control file: '/u01/app/oracle/oradata/beijing/control01.ctl'
ORA-27047: unable to read the header block of file  : 看见没赤裸裸的提示:找不到文件头-- 控制文件头都找不到怎么读取啊!!
Additional information: 2
Mon Mar 14 20:38:54 2011
ORA-205 signalled during: ALTER DATABASE   MOUNT...


说明不能读取到文件头!悲剧发生,重建控制文件!


4. 万幸由于,日志,数据均健在,所以,套模板格式,重建控制文件:

create controlfile reuse database "BEIJING" noresetlogs archivelog : 这位仁兄采用的是 noresetlog方式:因为redo健全,当然采用这种方式,而且不会丢失数据:
maxlogfiles 16
maxlogmembers 3
maxdatafiles 100
maxinstances 8
maxloghistory 292
datafile
'/u01/app/oracle/oradata/beijing/system01.dbf',
'/u01/app/oracle/oradata/beijing/sysaux01.dbf',
'/u01/app/oracle/oradata/beijing/undotbs01.dbf',
'/u01/app/oracle/oradata/beijing/user01.dbf',
'/u01/app/oracle/oradata/beijing/user02.dbf',
'/u01/app/oracle/oradata/beijing/xx.dbf',
'/u01/app/oracle/oradata/beijing/yy.dbf'
logfile
group 1 '/u01/app/oracle/oradata/beijing/redo01.log',
group 2 '/u01/app/oracle/oradata/beijing/redo02.log',
group 3 '/u01/app/oracle/oradata/beijing/redo03.log'
character set we8iso8859p1
/

重建完控制文件后,数据库已经自动mount
SYS@bj> select status from v$instance;

STATUS
------------
MOUNTED

5. 但是,此时打开数据文件却需要恢复:
SYS@bj> alter database open;
alter database open
*
ERROR at line 1:
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '/u01/app/oracle/oradata/beijing/system01.dbf'  :从第一个数据文件开始检查,发现需要进行恢复,因为数据头的scn号和最早的那个redo log scn号不匹配。

可以采用一个一个恢复的方式:
SYS@bj> recover datafile 1;
Media recovery complete.

更好的方法是:
SYS@bj> recover database;  // 恢复全部的数据文件----
Media recovery complete.

我们来比较下没有被破坏前和恢复之后,控制文件的大小:
没被破坏之前:
[oracle@milo beijing]$ ll control0*
-rw-r----- 1 oracle oinstall 7389184 Mar 14 20:35 control01.ctl
-rw-r----- 1 oracle oinstall 7389184 Mar 14 20:35 control02.ctl

恢复之后:
[oracle@milo beijing]$ ll control0*     
-rw-r----- 1 oracle oinstall 7389184 Mar 14 20:56 control01.ctl
-rw-r----- 1 oracle oinstall 7389184 Mar 14 20:56 control02.ctl

大小不带差一个字节!

6. 那么打开数据库,查看一下数据:
SYS@bj> alter database open;  //  恢复完后,所有scn均一样了。

Database altered.

SYS@bj> select count(*) from scott.t3;

  COUNT(*)
----------
         5
数据也是正确的,重建控制文件成功!!!

---------------------------------------------------------------------------

法二.b:使用跟踪文件重建控制文件
1. 把控制文件的重建语句生成到udump里 
SYS@bj> alter database backup controlfile to trace;

Database altered.

2. 查看相应文件
[oracle@milo beijing]$ ll -th $ORACLE_BASE/admin/beijing/udump/  | head -n 2
total 324K
-rw-r----- 1 oracle oinstall  11K Mar 14 21:03 bj_ora_5794.trc

[oracle@milo beijing]$ tail -n 130 $ORACLE_BASE/admin/beijing/udump/bj_ora_5794.trc
一段noresetlogs的重建sql:
STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "BEIJING" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 '/u01/app/oracle/oradata/beijing/redo01.log'  SIZE 50M,
  GROUP 2 '/u01/app/oracle/oradata/beijing/redo02.log'  SIZE 50M,
  GROUP 3 '/u01/app/oracle/oradata/beijing/redo03.log'  SIZE 50M
-- STANDBY LOGFILE
DATAFILE
  '/u01/app/oracle/oradata/beijing/system01.dbf',
  '/u01/app/oracle/oradata/beijing/undotbs01.dbf',
  '/u01/app/oracle/oradata/beijing/sysaux01.dbf',
  '/u01/app/oracle/oradata/beijing/user01.dbf',
  '/u01/app/oracle/oradata/beijing/xx.dbf',
  '/u01/app/oracle/oradata/beijing/yy.dbf',
  '/u01/app/oracle/oradata/beijing/user02.dbf'
CHARACTER SET WE8ISO8859P1
;

3. 破坏控制文件
SYS@bj> select 'host echo 111 > ' || name from v$controlfile;

'HOSTECHO111>'||NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
host echo 111 > /u01/app/oracle/oradata/beijing/control01.ctl
host echo 111 > /u01/app/oracle/oradata/beijing/control02.ctl

执行破坏,破坏后,切换日志:
SYS@bj> alter system switch logfile;
alter system switch logfile
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel

报错,不在连接到通信终止。

Oracle实例崩溃
SYS@bj> ho ps -ef | grep ora_
oracle    6025  5465  0 21:12 pts/8    00:00:00 /bin/bash -c ps -ef | grep ora_
oracle    6027  6025  0 21:12 pts/8    00:00:00 grep ora_

之后的恢复和之前完全一致!!!

---------------------------------------------------------------------------

法三。用resetlogs模式建立控制文件

---------------------------------------------------------------------------

法四。使用老的备份控制文件,恢复数据库。
1. 备份一个控制文件(旧控制文件)
SYS@bj> alter database backup controlfile to '/u01/app/oracle/oradata/beijing/control.bk';//先创建这一刻的一个控制文件。

Database altered.


#如果已经存在,可以在最后加reuse,表示覆盖原来的文件。

2. 业务进行
SYS@bj> create table scott.tt as select * from scott.emp;//进行一些增删改操作,人为将原先的控制文件变“老”

Table created.

SYS@bj> select count(*) from scott.tt;

  COUNT(*)
----------
        14


# 切换多次日志(根据日志组数量)
SYS@bj> alter system switch logfile;

System altered.

SYS@bj> /

System altered.

SYS@bj> /

System altered.

使得当前的日志存盘。

SYS@bj> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS
FIRST_CHANGE# FIRST_TIM
------ ---------- ---------- ---------- ---------- --- ----------------
------------- ---------
     1          1          2   52428800          1 YES INACTIVE
655915 15-MAR-11
     2          1          3   52428800          1 YES INACTIVE
655917 15-MAR-11
     3          1          4   52428800          1 NO  CURRENT
655919 15-MAR-11

3. 模拟控制文件故障
SYS@bj> r
  1* select name from v$controlfile

NAME
--------------------------------------------------
/u01/app/oracle/oradata/beijing/control01.ctl
/u01/app/oracle/oradata/beijing/control02.ctl

SYS@bj> host echo 1 > /u01/app/oracle/oradata/beijing/control01.ctl

SYS@bj> host echo 1 > /u01/app/oracle/oradata/beijing/control02.ctl


3. 模拟控制文件故障
SYS@bj> r
  1* select name from v$controlfile

NAME
--------------------------------------------------
/u01/app/oracle/oradata/beijing/control01.ctl
/u01/app/oracle/oradata/beijing/control02.ctl

SYS@bj> host echo 1 > /u01/app/oracle/oradata/beijing/control01.ctl

SYS@bj> host echo 1 > /u01/app/oracle/oradata/beijing/control02.ctl


3. 模拟控制文件故障
SYS@bj> r
  1* select name from v$controlfile

NAME
--------------------------------------------------
/u01/app/oracle/oradata/beijing/control01.ctl
/u01/app/oracle/oradata/beijing/control02.ctl

SYS@bj> host echo 1 > /u01/app/oracle/oradata/beijing/control01.ctl

SYS@bj> host echo 1 > /u01/app/oracle/oradata/beijing/control02.ctl

#验证控制文件损坏,实例崩溃!
SYS@bj> select status from v$instacne;
select status from v$instacne
*
ERROR at line 1:
ORA-03135: connection lost contact


SYS@bj> conn / as sysdba
Connected to an idle instance.

4.用旧的控制文件恢复损坏文件, 
SYS@bj> host cp /u01/app/oracle/oradata/beijing/{control.bk,control01.ctl}

SYS@bj> host cp /u01/app/oracle/oradata/beijing/{control.bk,control02.ctl}


5. 启实例
SYS@bj> startup   
ORACLE instance started.

Total System Global Area  293601280 bytes
Fixed Size                  1219016 bytes
Variable Size             234882616 bytes
Database Buffers           50331648 bytes
Redo Buffers                7168000 bytes
Database mounted.
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open:必须用这两种模式中的一种打开数据库。

SYS@bj> alter database open noresetlogs;//只要用旧的控制文件,那么必须resetlog方式打开。
alter database open noresetlogs
*
ERROR at line 1:
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done

使用就控制文件,应用日志去恢复数据库
SYS@bj> recover database using backup controlfile;
ORA-00279: change 655735 generated at 03/15/2011 14:21:35 needed for thread 1
ORA-00289: suggestion : /arc1/1_1_745856495.arc
ORA-00280: change 655735 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
auto
ORA-00279: change 655915 generated at 03/15/2011 20:19:59 needed for thread 1
ORA-00289: suggestion : /arc1/2_1_745856495.arc
ORA-00280: change 655915 for thread 1 is in sequence #2
ORA-00278: log file '/arc1/1_1_745856495.arc' no longer needed for this
recovery


ORA-00279: change 655917 generated at 03/15/2011 20:20:00 needed for thread 1
ORA-00289: suggestion : /arc1/3_1_745856495.arc
ORA-00280: change 655917 for thread 1 is in sequence #3
ORA-00278: log file '/arc1/2_1_745856495.arc' no longer needed for this
recovery


ORA-00279: change 655919 generated at 03/15/2011 20:20:06 needed for thread 1
ORA-00289: suggestion : /arc1/4_1_745856495.arc
ORA-00280: change 655919 for thread 1 is in sequence #4
ORA-00278: log file '/arc1/3_1_745856495.arc' no longer needed for this
recovery


ORA-00308: cannot open archived log '/arc1/4_1_745856495.arc'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
Additional information: 3

# 根据日志切换顺序给定sequence #4的日志,也可以由日志的文件看出
SYS@bj> recover database using backup controlfile;//使用旧的控制文件打开---
ORA-00279: change 655919 generated at 03/15/2011 20:20:06 needed for thread 1
ORA-00289: suggestion : /arc1/4_1_745856495.arc
ORA-00280: change 655919 for thread 1 is in sequence #4


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u01/app/oracle/oradata/beijing/redo03.log
Log applied.
Media recovery complete.

重置日志,打开数据库
SYS@bj> alter database open resetlogs;// 因为是使用旧的控制文件打开的,所以只能用resetlog,即使redo和归档没丢。

Database altered.

6. 数据验证:
SYS@bj> select count(*) from scott.tt;

  COUNT(*)
----------
        14




---------------------------------------------------------------------------


******************
总结:
******************
一。控制文件的主要作用:
1. 描述了数据库的结构:
从重建语句不难看出,数据文件,日志文件,库名,归档模式等都记录在控制文件里。

2. 描述了数据库的行为:
文件都写到哪了,恢复时,告诉新控制文件终点。

二。max开头的参数决定了控制文件的大小。

三。alter database backup controlfile to trace只能在mount和open下运行,因为,这样能保证控制文件没有问题。

终极总结:

关于recover database的一些理解
在普通的recover database 或者 recover tablespace, recover datafile时, Oracle会以当前controlfile所纪录的SCN为准,利用archive log和 redo log的redo entry, 把相关的datafile 的 block恢复到“当前controlfile所纪录的SCN”
而某些情况下,Oracle需要把数据恢复到比当前controlfile所纪录的SCN还要靠后的位置(比如说,control file是backup controlfile , 或者 controlfile是根据trace create的。),这时候,就需要用using backup controlfile. 恢复就不会受“当前controlfile所纪录的SCN”的限制。

这时候的限制就来自于你的语句(until time , until scn),或者可用的archive log(until cancel)
startup nomount后, 
recover database,


其实:

要理解recover database using backup controlfile,先理解 recover database 
也就是说,不加using backup controlfile的情况。
在普通的recover database 或者 recover tablespace, recover datafile时, Oracle会以当前controlfile所纪录的SCN为准,利用archive log和 redo log的redo entry, 把相关的datafile 的 block恢复到“当前controlfile所纪录的SCN”

也就是说:recovery database: 代表完全恢复。如果你丢了redo ,那么通过trace reset log 方式重建控制文件,因为你无法进行完全恢复了,并且还需要进行 alter database open reset log --

而某些情况下,Oracle需要把数据恢复到比当前controlfile所纪录的SCN还要靠后的位置(比如说,control file是backup controlfile , 或者 controlfile是根据trace create的。),这时候,就需要用using backup controlfile. 恢复就不会受“当前controlfile所纪录的SCN”的限制。
这时候的限制就来自于你的语句(until time , until scn),或者可用的archive log(until cancel) ...


很多人说,resetlogs就是不完全恢复,这是不对的。

做不完全恢复必须使用resetlogs,但resetlogs也可以做完全恢复,比如上面的最后一种情况:通过旧的控制文件备份来恢复。

而noresetlogs则是必须做完全恢复时使用:比如通过trace 的noresetlog 恢复

resetlogs会重置日志序列号强制清空或重建REDO,而noresetlogs则不会这么做。
第1:我们假设仅仅控制文件丢失,而其他文件没有丢失(主要是归档和REDO),那么恢复的时候如果选择从备份中恢复控制文件。恢复后,控制文件会去读数据文件头中与CHECKPOINT SCN对应的RBA信息来确定从那个序列的归档日志开始恢复,一直推进恢复到NEXT SCN是无穷大的那个REDOLOG,此时恢复是完全恢复的,但打开的时候还要以resetlogs方式打开,这样要重置归档日志的sequence,也就是说,如果你恢复时使用了备份控制文件,那么打开数据库时必然是要resetlogs的。
 
第二种情况,不完全恢复,不管你是要什么样的不完全恢复,SCN,TIME,跨越REDO,都必须使用resetlogs。


第三种情况,丢失REDOLOG,这就更需要resetlogs了,因为resetlogs能够重建REDOLOG。如果你的REDOLOG、控制文件、数据文件丢失的话,需要先恢复控制文件,然后restore database;recover database;alter database open resetlogs;注意,这时候做的是不完全恢复,因为REDO没有了。在recover过程中可能会报错然后自动退出RMAN,无视,alter database open resetlogs即可。


第四种情况,没有丢失控制文件及各种日志,仅丢失数据文件,这种问题比较常见,有可能磁盘损坏造成数据文件丢失,等磁盘故障排除后,需要恢复,此时的恢复就很简单了,restore database;recover database;alter database open;就一切OK,也就是说,在不使用备份控制文件恢复的情况下,是可以使用noresetlog方式打开数据库的。前提有一,不能丢失日志文件。假若丢失了控制文件和数据文件但还是想以noresetlog打开的话,就必须手动以noresetlogs方式重建控制文件,而且REDOLOG的状态都必须正常,否则是无法使用noresetlogs方式打开。



备注:
使用resetlogs打开数据库后无必完整地备份一次数据库。
3、create controlfile resetlogs/noresetlogs
1).用Noresetlogs重建控制文件时,控制文件中 datafile Checkpoint来自Online logs中的Current log头
2).用Resetlogs重建控制文件时,控制文件中datafile Checkpoint来自各数据文件头。

再回顾下通过trace 重建控制文件:


NORESETLOGS重建步骤
1.执行脚本,重建控制文件(CREATE CONTROLFILE REUSE DATABASE "HOEGH"NORESETLOGS NOARCHIVELOG......)
2.执行介质恢复RECOVER DATABASE
3.打开数据库ALTER DATABASE OPEN;
4.添加临时表空间

RESETLOGS重建步骤
1.执行脚本,重建控制文件(CREATE CONTROLFILE REUSE DATABASE "HOEGH"RESETLOGS NOARCHIVELOG......)
2.执行介质恢复RECOVER DATABASE USING BACKUP CONTROLFILE
3.打开数据库ALTER DATABASE OPEN RESETLOGS;
4.添加临时表空间




再加上一个相关链接:http://blog.itpub.net/23135684/viewspace-721927/

这篇文章主要说的是:

当如果你使用 trace resetlog  方式重建的数据文件,那么:

如果数据库是 abort 方式关闭的,则:RECOVER DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL;  <=========必须使用UNTIL CANCEL

如果数据库是正常关闭的,则:RECOVER DATABASE USING BACKUP CONTROLFILE 可以不加UNTIL CANCEL


 致使我重新认识recover database using backup controlfile until cancel;语句的原因是昨天客户由于存储控制器故障导致Oracle 11.2.0.4 for Solaris的RAC其中一个数据库无法OPEN,告警日志收到如下的错误:
ORA-600 [kcrfr_read_5], [4475], ......
非常遗憾的是MOS和ORA-600 Tools上没有任何和该错误相关的信息,最后其他同事通过执行下面的语句将数据库OPEN:
SQL> recover database using backup controlfile until cancel;
SQL> alter database open resetlogs;

从trace文件来看,Oracle数据库是在instance recovery阶段,读取redo日志文件时报的此ORA-600的错误,客户的Oracle Redo做了冗余。

首先我们来看如下一段对该语句的描述:
Recover database using backup controlfile until cancel

What is checked or what happens when we run "recover database using backup controlfile until cancel;"? What does this command do and when do we use this command?

        If you were to recover the database with a current control file, Oralce will know the last SCN of the last checkpoint. So Oracle can use the information in the archived and online redo logs to apply recovery up to that SCN. This is called a "complete" recovery.
       如果控制文件是最新,那么这种恢复叫做完全恢复,Oracle可以使用控制文件来引导将数据库恢复到最新的状态,没有加上using backup controlfile即是这种情况。

        If you do not have the current control file, your option is to use a backup controlfile. Which means Oracle does not know the SCN to stop applying recovery. So you tell Oracle that you are using a "backup controlfile" and that you will tell it when to stop applying redo by replying "cancel." When Oracle starts recovery, it looks at the datafiles to know the last time a checkpoint was performed on the datafile. Oracle now knows to start applying recovery to the datafile for all SCNs after the SCN in the datafile header. Oracle rolls forward transactions. But Oracle does not know when to stop, and eventually, Oracle applies recovery in all of your archived redo logs. You can then tell Oracle to use the redo in the online redo logs. Oracle will ask you where to find more redo. At this point, you tell it to quit applying redo by replying CANCEL.
    如果使用using backup controlfile字句,Oracle数据库将不会知道停止应用的SCN,这个时候就需要DBA介入来告诉Oracle数据库什么时候停止应用redo(cancel),Oracle可以通过存储在数据文件头中的CHECKPOINT SCN来知道所有数据文件开始恢复的SCN号,但是Oracle不知道什么时候停止,这个时候,Oracle会问你在什么地方找到归档Redo日志,在线Redo日志,以及更多的Redo,最后你必须通过CANCEL字句告诉Oracle退出Redo的应用。using backup controlfile是一种不完全恢复,需要DBA介入,until cancel是对不完全恢复画上句号。

        Hopefully, you never have to use this command. This is because you multiplex your control files and have three copies of the control file, all on different disk units. So if you lose a disk unit, you use the control files on the other disk units. The only time you need this command is when you lose all of your control files. In this case, either use a binary backup of the control file or you re-create the control file with the CREATE CONTROLFILE command and then recover with the backup control file.
       如果丢失了所有的控制文件及其副本,那么只能从备份恢复控制文件或重建控制文件,这个时候旧的控制文件是不能用于引导Oracle的恢复工作,就需要DBA的介入,使用USING BACKUP CONTROLFILE UNTIL CANCEL语句来引导Oracle数据库的恢复操作。

除了上面的描述外,我们再来看看Oracle文档是怎么说的:

Begin cancel-based recovery by issuing the following command:
RECOVER DATABASE UNTIL CANCEL
UNTIL CANCEL表示取消恢复操作。

If you are using a backup control file with this incomplete recovery, then specify the USING BACKUP CONTROLFILE option in the RECOVER command.
RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE
使用备份的控制文件执行不完全恢复,就要指定UNTIL BACKUP CONTROLFILE子句,USING BACKUP CONTROLFILE和UNTIL CANCEL不是一定要一起出现,当需要应用很多归档日志文件,在线日志文件时UNTIL CANCEL就不应该出现,只有在所有的归档和在线Redo日志应用结束后才可以加上UNTIL CANCEL画上句号,后面的实验证明UNTIL CANCEL也可以不出现。

有一个非常好的案例,就是重建控制文件,NORESETLOGS和RESETLOGS是有较大区别的,在使用RESETLOGS重建控制文件是需要使用USING BACKUP CONTROLFILE UNTIL CANCEL;语句。
参考文档:https://blogs.oracle.com/Database4CN/entry/%E5%A6%82%E4%BD%95%E9%87%8D%E5%BB%BArac%E7%9A%84%E6%8E%A7%E5%88%B6%E6%96%87%E4%BB%B6

   注意:在这个文档中说,以RESETLOGS模式重建的控制文件,执行RECOVER的时候要加上UNTIL CANCEL字句,实际上,生成的CONTROLFILE重建TRACE文件中并没有加上UNTIL CANCEL字句,实际的测试情况如下:

1).SHUTDOWN ABORT关闭数据库实例。
    如果是以SHUTDOWN ABORT的模式关闭的数据库,以RESETLOGS模式重建了控制文件,执行RECOVER DATABASE USING BACKUP CONTROLFILE(没有加上UNTIL CANCEL)执行不完全恢复,为了将数据库恢复到一致性的状态,指定最新的Redo日志文件,手动将数据库恢复到最新,即可以OPEN RESETLOGS打开数据库。

SQL> shutdown abort
ORACLE instance shut down.
SQL> startup nomount
ORACLE instance started.

Total System Global Area 1570009088 bytes
Fixed Size                  2221840 bytes
Variable Size            1140852976 bytes
Database Buffers          419430400 bytes
Redo Buffers                7503872 bytes
SQL> CREATE CONTROLFILE REUSE DATABASE "HELLO" RESETLOGS  NOARCHIVELOG
  2      MAXLOGFILES 16
  3      MAXLOGMEMBERS 3
  4      MAXDATAFILES 100
  5      MAXINSTANCES 8
  6      MAXLOGHISTORY 292
  7  LOGFILE
  8    GROUP 1 '/oradata/hello/redo01.log'  SIZE 50M BLOCKSIZE 512,
  9    GROUP 2 '/oradata/hello/redo02.log'  SIZE 50M BLOCKSIZE 512,
 10    GROUP 3 '/oradata/hello/redo03.log'  SIZE 50M BLOCKSIZE 512
 11  DATAFILE
 12    '/oradata/hello/system01.dbf',
 13    '/oradata/hello/sysaux01.dbf',
 14    '/oradata/hello/undotbs01.dbf',
 15    '/oradata/hello/users01.dbf',
 16    '/u01/app/oracle/product/11.2.0/db_1/dbs/soe.dbf'
 17  CHARACTER SET AL32UTF8
 18  ;

Control file created.

SQL>RECOVER DATABASE USING BACKUP CONTROLFILE;
ORA-00279: change 1302781 generated at 07/21/2015 12:04:45 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_1_%u_.arc
ORA-00280: change 1302781 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/oradata/hello/redo02.log
ORA-00339: archived log does not contain any redo
ORA-00334: archived log: '/oradata/hello/redo02.log'


SQL> RECOVER DATABASE USING BACKUP CONTROLFILE;
ORA-00279: change 1302781 generated at 07/21/2015 12:04:45 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_1_%u_.arc
ORA-00280: change 1302781 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/oradata/hello/redo03.log
ORA-00339: archived log does not contain any redo
ORA-00334: archived log: '/oradata/hello/redo03.log'


SQL> RECOVER DATABASE USING BACKUP CONTROLFILE;
ORA-00279: change 1302781 generated at 07/21/2015 12:04:45 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_1_%u_.arc
ORA-00280: change 1302781 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/oradata/hello/redo01.log
Log applied.
Media recovery complete.
SQL> alter database open resetlogs;       

Database altered.

SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/oradata/hello/temp01.dbf'
  2       SIZE 390070272  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;

Tablespace altered.

2).SHUTDOWN IMMEDIATE关闭数据库实例。
    如果是以SHUTDOWN IMMEDIATE模式关闭的数据库,由于重建了控制文件,只能通过DBA接入引导数据库的恢复,但由于数据库是正常关闭,没有可恢复的操作,所以必须明确的指定UNTIL CANCEL字句完成RECOVER操作,之后才能使用OPEN RESETLOGS打开数据库。

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup nomount 
ORACLE instance started.

Total System Global Area 1570009088 bytes
Fixed Size                  2221840 bytes
Variable Size            1140852976 bytes
Database Buffers          419430400 bytes
Redo Buffers                7503872 bytes
SQL> CREATE CONTROLFILE REUSE DATABASE "HELLO" RESETLOGS  NOARCHIVELOG
  2      MAXLOGFILES 16
  3      MAXLOGMEMBERS 3
  4      MAXDATAFILES 100
  5      MAXINSTANCES 8
  6      MAXLOGHISTORY 292
  7  LOGFILE
  8    GROUP 1 '/oradata/hello/redo01.log'  SIZE 50M BLOCKSIZE 512,
  9    GROUP 2 '/oradata/hello/redo02.log'  SIZE 50M BLOCKSIZE 512,
 10    GROUP 3 '/oradata/hello/redo03.log'  SIZE 50M BLOCKSIZE 512
 11  DATAFILE
 12    '/oradata/hello/system01.dbf',
 13    '/oradata/hello/sysaux01.dbf',
 14    '/oradata/hello/undotbs01.dbf',
 15    '/oradata/hello/users01.dbf',
 16    '/u01/app/oracle/product/11.2.0/db_1/dbs/soe.dbf'
 17  CHARACTER SET AL32UTF8
 18  ;

Control file created.

SQL> recover database using backup controlfile;
ORA-00279: change 1304028 generated at 07/21/2015 12:26:44 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_1_%u_.arc
ORA-00280: change 1304028 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
cancel
Media recovery cancelled.
SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '/oradata/hello/system01.dbf'


SQL>recover database using backup controlfile until cancel;
ORA-00279: change 1304028 generated at 07/21/2015 12:26:44 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_1_%u_.arc
ORA-00280: change 1304028 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
cancel 
Media recovery cancelled.
SQL> alter database open resetlogs;

Database altered.


Because online redo logs are not backed up, you cannot restore them with the datafiles and control files. In order to allow Oracle to reset the online redo logs, you must first mimic incomplete recovery:
RECOVER DATABASE UNTIL CANCEL
CANCEL
在线Redo日志文件是没有备份的(建议做好冗余),为了允许Oracle重置在线日志文件,必须首先使用UNTIL CANCEL模拟不完全恢复。
这句话实际和这次遇到的问题比较类似,ORA-600的错误一般是逻辑上的错误,例如,逻辑坏块等,客户在可接受少量数据丢失的情况下,就可考虑放弃逻辑损坏的Redo日志文件,将其重置,重置即需要使用OPEN RESETLOGS打开数据库,模拟一个不完全恢复,那么久需要使用UNTIL CANCEL字句。

参考文档:http://docs.oracle.com/cd/A97630_01/server.920/a96572/performingreco.htm


下面再通过一些实际的操作验证这条命令:

实验1:

SQL> select * from v$version where rownum <=2;


BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production

SQL> shutdown abort

ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 1570009088 bytes
Fixed Size                  2221840 bytes
Variable Size            1140852976 bytes
Database Buffers          419430400 bytes
Redo Buffers                7503872 bytes
Database mounted.
SQL> recover database until cancel;
ORA-00279: change 1281000 generated at 07/21/2015 11:25:36 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_32_%u_.ar
c
ORA-00280: change 1281000 for thread 1 is in sequence #32


Specify log: {<RET>=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: '/oradata/hello/system01.dbf'

ORA-01112: media recovery not started


SQL> alter database open;  
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open

SQL> alter database open noresetlogs;

Database altered.

或者

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: '/oradata/hello/system01.dbf'

<<<< 一旦recover database指定了UNTIL CANCEL字句,就相当于模拟了不完全恢复,OPEN数据库的时候可以指定RESETLOGS和RESETLOGS来选择是否重置REDO日志文件。如果选择NORESETLOGS,Oracle继续自动的执行实例恢复,打开数据库;如果选择RESETLOGS,Oracle将需要恢复数据文件到一致性的状态,CANCEL是指不完全恢复的结束点,并没有放弃部分Redo数据恢复的含义,数据库是必须恢复到一致性的状态,不完全恢复可基于SCN,TIME,和SEQUENCE。

<<<< UNTIL CANCEL可以模拟不完全恢复,需要DBA介入,手工指定相应的Redo日志文件位置。

SQL> recover database using backup controlfile until cancel;
ORA-00279: change 1281000 generated at 07/21/2015 11:25:36 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_32_%u_.ar
c
ORA-00280: change 1281000 for thread 1 is in sequence #32


Specify log: {<RET>=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: '/oradata/hello/system01.dbf'


ORA-01112: media recovery not started

<<<< 加入using backup controlfile表示不使用当前的控制文件来引导恢复,由DBA介入控制恢复进程。

SQL> recover database;
ORA-00283: recovery session canceled due to errors
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done

<<<< 放弃使用当前控制文件引导备份之后就不能重新再使用当前控制文件引导备份。

SQL> recover database using backup controlfile;
ORA-00279: change 1281000 generated at 07/21/2015 11:25:36 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_32_%u_.ar
c
ORA-00280: change 1281000 for thread 1 is in sequence #32


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/oradata/hello/redo02.log
Log applied.
Media recovery complete.
SQL> alter database open ;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open


SQL> alter database open resetlogs;     

Database altered.

<<<<  在做不完全恢复的时候,UNTIL CANCEL这个句号不是一定要打, 在OPEN的时候不完全恢复的周期已经结束。


实验2:
SQL> shutdown abort
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area 1570009088 bytes
Fixed Size                  2221840 bytes
Variable Size            1140852976 bytes
Database Buffers          419430400 bytes
Redo Buffers                7503872 bytes
Database mounted.
SQL> recover database using backup controlfile;
ORA-00279: change 1301730 generated at 07/21/2015 11:42:08 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/HELLO/archivelog/2015_07_21/o1_mf_1_2_%u_.arc
ORA-00280: change 1301730 for thread 1 is in sequence #2


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/oradata/hello/redo02.log
Log applied.
Media recovery complete.

<<<< 单独使用using backup controlfile,表示放弃使用当前控制文件引导数据库的恢复,需要DBA介入,指定Redo日志文件位置,属于不完全恢复。

SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open


SQL> alter database open noresetlogs;
alter database open noresetlogs
*
ERROR at line 1:
ORA-01588: must use RESETLOGS option for database open


SQL> alter database open resetlogs;

Database altered.

<<<< 但指定了USING BACKUP CONTROLFILE字句恢复,在OPEN的时候不能指定NORESETLOGS打开,只能以RESETLOGS打开,单独使用UNTIL CANCEL是依然可以使用NORESETLOGS打开数据库。

--end--

0 0