恢复控制文件避免使用resetlogs选项 (r10笔记第12天)

时间:2022-05-04
本文章向大家介绍恢复控制文件避免使用resetlogs选项 (r10笔记第12天),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在搭建Data Guard的时候,我们可以直接从主库生成一个备库控制文件,或者拷贝一个备库的控制文件即可,后续的工作就交给Data Guard来自动恢复完成了,尤其是使用rman备份恢复的时候,使用recover database是一气呵成,我们无须理会其中更多的细节,当然实际上Oracle已经帮我们处理好了。 我们都知道控制文件的备份有两种方式,一种是镜像,一种是trace。镜像备份方式类似alter database backup controlfile to 'xxxxx'这样的形式,而trace备份则类似于alter database backup controlfile to trace这样的形式。 从不少实际的操作中,我发现镜像的恢复方式会带来不少的困扰,如果是一个新人来做控制文件的恢复,可能会栽入不少坑里。最后一番折腾可能会带来一种直观的感觉就是控制文件实在太重要了,如果要恢复,操作复杂度和不完全恢复差不多。而且最让人纠结的是,折腾一番之后,还要resetlogs的方式open数据库,我不喜欢这种恢复方式,明明完全恢复,为什么需要这么多的弯路。我们可能在rman中也设置了autobackup,在11g中其实是有隐含参数来控制延迟创建,默认是5分钟。可见控制文件还是给很多人带来了太多困扰。 那么怎么恢复控制文件比较好呢。怎么使得控制文件的恢复无需resetlogs呢。其实实现起来很简单。 我们先来看看纠结的镜像恢复方式。首先是备份。 sys@OCP11G> alter database backup controlfile to '/home/ora11g/ctl.bak' reuse; Database altered. [ora11g@jeanron100 ~]$ sqlplus / as sysdba sys@OCP11G> select *from v$controlfile; STATUS ------- NAME ------------------------------------------------ IS_ BLOCK_SIZE FILE_SIZE_BLKS --- ---------- -------------- /u01/app/ora11g/oradata/ocp11g/control01.ctl NO 16384 614 /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl NO 16384 614 2 rows selected. 我们手工删除控制文件 [ora11g@jeanron100 ~]$ rm /u01/app/ora11g/oradata/ocp11g/control01.ctl [ora11g@jeanron100 ~]$ rm /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl 这个时候停库会报错,所以只能是abort方式的断电重启。 sys@OCP11G> shutdown immediate ORA-00210: cannot open the specified control file ORA-00202: control file: '/u01/app/ora11g/oradata/ocp11g/control01.ctl' ORA-27041: unable to open file Linux-x86_64 Error: 2: No such file or directory Additional information: 3 sys@OCP11G> shutdown abort ORACLE instance shut down. 然后重启启动到nomount sys@OCP11G> startup nomount 然后开始还原控制文件。 [ora11g@jeanron100 ~]$ cp /home/ora11g/ctl.bak /u01/app/ora11g/oradata/ocp11g/control01.ctl [ora11g@jeanron100 ~]$ cp /home/ora11g/ctl.bak /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl 接着mount就没有问题了。 idle> alter database mount; Database altered. 当然在启库的时候肯定会有下面的提示信息,需要设置为resetlogs模式。 idle> alter database open; alter database open * ERROR at line 1: ORA-01589: must use RESETLOGS or NORESETLOGS option for database open 当然我们尝试resetlogs,结果还是会有一连串的ORA错误抛出来。而在尝试recover的时候会提示recover using backup controlfile idle> recover database; ORA-00283: recovery session canceled due to errors ORA-01610: recovery using the BACKUP CONTROLFILE option must be done 这个时候会折腾几次,因为归档中的数据变化都应用完了,数据库不知道该从哪个redo中恢复,这个就给问题的解决铺下了障碍。我们需要带着一丝的运气逐个输入redo的路径,快则一次搞定,满则需要多轮验证。 idle> recover database using backup controlfile; ORA-00279: change 1178971 generated at 09/04/2016 02:03:43 needed for thread 1 ORA-00289: suggestion : /u01/app/ora11g/flash_recovery_area/OCP11G/archivelog/2016_09_04/o1_mf_1_25_%u_.arc ORA-00280: change 1178971 for thread 1 is in sequence #25 Specify log: {<RET>=suggested | filename | AUTO | CANCEL} 当然费了一番周折还是提示要resetlogs idle> alter database open; alter database open * ERROR at line 1: ORA-01589: must use RESETLOGS or NORESETLOGS option for database open 而改进的方式就是使用trace的方式,我们在这个基础上继续补充,就不需要resetlogs了。 因为已经恢复了控制文件,但是似乎控制文件的SCN已经比数据文件头部要旧了。不过整体来看,数据文件的信息没有变化,只有最后的SCN的部分有一些差别,那么我们就可以使用trace的方式来弥补。 idle> startup nomount idle> CREATE CONTROLFILE REUSE DATABASE "OCP11G" NORESETLOGS ARCHIVELOG 2 MAXLOGFILES 16 3 MAXLOGMEMBERS 3 4 MAXDATAFILES 100 5 MAXINSTANCES 8 6 MAXLOGHISTORY 292 7 LOGFILE 8 GROUP 1 '/u01/app/ora11g/oradata/ocp11g/redo01.log' SIZE 50M BLOCKSIZE 512, 9 GROUP 2 '/u01/app/ora11g/oradata/ocp11g/redo02.log' SIZE 50M BLOCKSIZE 512, 10 GROUP 3 '/u01/app/ora11g/oradata/ocp11g/redo03.log' SIZE 50M BLOCKSIZE 512 11 -- STANDBY LOGFILE 12 DATAFILE 13 '/u01/app/ora11g/oradata/ocp11g/system01.dbf', 14 '/u01/app/ora11g/oradata/ocp11g/sysaux01.dbf', 15 '/u01/app/ora11g/oradata/ocp11g/undotbs01.dbf', 16 '/u01/app/ora11g/oradata/ocp11g/users01.dbf', 17 '/u01/app/ora11g/oradata/ocp11g/testdata01.dbf', 18 '/u01/app/ora11g/oradata/ocp11g/testdata02.dbf' 19 CHARACTER SET UTF8 20 ; idle> recover database ; Media recovery complete. idle> alter database open; Database altered. 这个过程中直接alter database open也没有问题,问题引刃而解。 这个修复的过程让我想起来MySQL中的GTID,就是一个全局的标记位。使得搭建slave的时候更加省心,大多数情况其实我们也不需要知道更细节的 SCN,交给MySQL自己去判断就好。对于Oracle的恢复来说也是如此,我们可以借助Oracle提供的完善的后台服务来完成这个恢复工作,而无需 使用resetlogs,何乐而不为。