oracle-控制文件的备份和恢复

本篇将介绍各种备份及恢复控制文件的方法,在介绍恢复时,以备份和重做日志(包括归档日志和在线日志)没有丢失为前提

无备份情况下的控制文件恢复参考13.3,丢失重做日志的情况请参考12篇“不完全数据库恢复”

8.1 控制文件损坏的后果

数据库的控制文件不止一个,进程对其写的操作是针对所有的控制文件,并且写的内容是相同的,所以多个控制文件的内容是完全一样的;

当进程读取控制文件时,读的却总是第一个控制文件的内容(第一个控制文件的定义时control_files初始化参数的第一个文件)。当第一个控制文件损坏,读写操作都是出错。

8.1.1 实例启动时发现损坏

YHQT@ orcl >show parameter control_files
NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
control_files			     string	 /u01/app/oracle/oradata/orcl/c
						 ontrol01.ctl, /u01/app/oracle/
						 oradata/orcl/control02.ctl

3个文件中,任意一个出错,实例将启动不到mount阶段,启动报错

--ORA-00205: error in identifying control file, check alert log for more info

其中一个文件损坏

--ORA-00227: corrupt block detected in control file: (block 0, # blocks )

如果是3个文件全部被删除

ORA-00210: cannot open the specified control file

ORA-00202: control file: '/u01/app/oracle/oradata/orcl/control01.ctl'

场景1db启动时,任意一个控制文件的数据块损坏时的告警

SQL> startup mount;
ORACLE instance started.
Total System Global Area 1185853440 bytes
Fixed Size     2252664 bytes
Variable Size   754974856 bytes
Database Buffers   419430400 bytes
Redo Buffers     9195520 bytes
ORA-00227: corrupt block detected in control file: (block 0, # blocks )

场景2db启动时,任意一个控制文件头损坏,告警日志

ORA-00210: cannot open the specified control file
ORA-00202: control file: '/u01/app/oracle/oradata/orcl/control01.ctl'
ORA-27048: skgfifi: file header information is invalid
ORA-205: signalled during: ALTER DATABASE MOUNT ...

场景3db启动时,任意控制文件丢失

ORA-00210: cannot open the specified control file
ORA-00202: control file: '/u01/app/oracle/oradata/orcl/control01.ctl'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
ORA-205 signalled during: ALTER DATABASE   MOUNT...

8.1.2 实例运行时发现损坏

如果任意一个控制在实例运行时损坏,实例起先能够保持OPEN状态,但不能保证所有功能可以正常进行:某些操作可以正常使用,某些直接报错,

最终,实例还是要被关闭(自动或手动)。首先发现问题的极有可能是CKPT进程(该进程每3秒就会写一下控制文件),在alert文件中

ORA-00227: corrupt block detected in control file: (block 1, # blocks 1)

ORA-00202: control file: '/u01/app/oracle/oradata/orcl/control01.ctl'

此时,CKPT将不停的报错,11g自动的洪流控制会选择性的屏蔽重复信息的产生,因为每3秒更新的不属于特别重要的检查点信息,

而是一种对在线重做日志最新状态和当前SCN号的确认信息,只要重做日志健康,这些信息还是可以从重做日志中取得的,实例也不会终止。

对于服务器进程来说,执行一些需要对控制文件读写(只要第一个文件健康,读写操作不报错)的操作,同样也会报错,比如v$database\v$log\v$logfile\v$datafile\v$tempfile等动态视图

SQL> select * from v$datafile;
ORA-00227: corrupt block detected in control file: (block 1, # blocks 1)
ORA-00202: control file: '/u01/app/oracle/oradata/orcl/control01.ctl'

比如再创建表空间

SQL>create tablespace yhqt datafile '/u01/app/oracle/oradata/orcl/yhqt01.dbf' size 50M;

也会报同样的错误

CKPT会在发起检查点时终止实例,因为检查点需要写控制文件,并且检查点被认为是不允许有任何差错的重要操作

CKPT (ospid:15711): terminating the instance due to error 227

即使发起命令alter system switch logfile日志切换命令,LGWR也会终止实例。切换日志的完整性操作包括把日志序列号更新到控制文件,而控制文件损坏,无法更新,

LWGR(ospid:11529): terminating the instance due to error 227

在实例被终止前,只要不直接或间接地访问控制文件,服务器进程的一切(select\dml\ddl\commit\rollback)等可以正常执行。否则,轻则报错,重则服务器进程被杀导致实例被终止。

SQL> alter tablespace example read only; ---实例将被终止

当遇到这种情况,如果实例还没有被关闭,能提交的事务可以抓紧提交,因为commit重做记录写入在线日志可以进行,然后shutdown abort;

SQL> shutdown abort;

场景4:实例正常运行,在linuxrm删除掉控制文件

这种情况实例不会被关闭,CKPT,LGWR进程已经打开了控制文件,而rm命令并不能把这些进程已经打开的控制文件的句柄删掉,

也没有真正地物理上把控制文件删掉,rm只是在文件系统上删除了指向控制文件的“索引”而已。

8.2 备份控制文件

控制文件的备份类型主要分为:在线镜像备份、自动备份和手动备份

8.2.1 在线镜像备份

在线镜像备份,或称为在线副本的路径,有control_files参数指定

YHQT@ orcl >show parameter control_files

8.2.2 自动备份

--1 显示自动备份

显示自动备份功能默认是关闭的,在没有catalog的情况下,建议打开,使用RMANconfigure命令设置

--show all
--rman> configure controlfile autobackup on;
RMAN> show controlfile autobackup;
RMAN configuration parameters for database with db_unique_name ORCL are:
CONFIGURE CONTROLFILE AUTOBACKUP ON;
RMAN> backup tablespace ogg;
Starting backup at 16-JUL-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00009 name=/u01/app/oracle/oradata/orcl/ogg01.dbf
channel ORA_DISK_1: starting piece 1 at 16-JUL-19
channel ORA_DISK_1: finished piece 1 at 16-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/backupset/2019_07_16/o1_mf_nnndf_TAG20190716T174825_glv7c9gc_.bkp tag=TAG20190716T174825 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 16-JUL-19
Starting Control File and SPFILE Autobackup at 16-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/autobackup/2019_07_16/o1_mf_s_1013795306_glv7cbwp_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 16-JUL-19 ---->自动备份控制文件和参数文件

当数据库物理结构发生变化时,如创建或删除表空间、添加或删除数据文件、表空间上下线切换、表空间可读写切换等,从11.2开始,这样的物理结构变化导致的自动备份oracleMMON后台进程延时处理

隐含参数_controlfile_autobackup_delay’修改时间间隔

--2 隐式自动备份

指即便在controlfile autobackup=off,只要使用RMAN备份system表空间的第一个数据文件,控制文件就会被自动备份。

RMAN> configure controlfile autobakcup off;
RMAN> backup datafile 1;

但是oracle并不认为这是自动备份,这种控制文件备份根本没有保存在快速恢复区的autobackup目录下,而是在backupset目录。

--3手动备份

使用RMANsqlplus手动备份控制文件。备份可分为备份集镜像复制备份和重建脚本

备份集和镜像复制的默认路径是快速恢复区,没有使用快速恢复区的一般在’$ORACLE_HOME/dbs目录。重建脚本则写入常规的追踪文件路径中。

--3.1 备份集备份

RMAN> backup as backupset current controlfile;
Starting backup at 17-JUL-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
including current control file in backup set
channel ORA_DISK_1: starting piece 1 at 17-JUL-19
channel ORA_DISK_1: finished piece 1 at 17-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/backupset/2019_07_17/o1_mf_ncnnf_TAG20190717T103715_glx2gwl8_.bkp tag=TAG20190717T103715 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 17-JUL-19
Starting Control File and SPFILE Autobackup at 17-JUL-19  ---》》自动备份了参数文件
piece handle=/u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 17-JUL-19
RMAN> list backup of controlfile;

--3.2 镜像复制备份

RMAN> backup as copy current controlfile format '/home/oracle/control.backup';
Starting backup at 17-JUL-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
copying current control file
output file name=/home/oracle/control.backup tag=TAG20190717T103956 RECID=2 STAMP=1013855996
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
Finished backup at 17-JUL-19
Starting Control File and SPFILE Autobackup at 17-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855997_glx2mxy4_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 17-JUL-19
或通过sqlplus备份控制文件
SYS@ orcl >alter database backup controlfile to '/home/oracle/control.backup.2';
Database altered.
RMAN> list copy of controlfile; ##查看镜像复制备份

--3.3 重建脚本

SYS@ orcl >alter database backup controlfile to trace as '/home/oracle/control20190717.sql';

Database altered.

不指定位置通过视图查询

SQL> select * from v$diag_info where name=’Default Trace File’;

查看脚本片段

[oracle@DSI ~]$ sed -n "/NORESETLOGS/,/REUSE AUTOEXTEND ON/p" /home/oracle/control20190717.sql |grep -v '^--'

首先实例启动到nomount,通过create controlfile创建控制文件(maxlogfileslogfiledatafile等)

[oracle@DSI ~]$ sed -n "/NORESETLOGS/,/REUSE AUTOEXTEND ON/p" /home/oracle/control20190717.sql |grep -v '^--'


STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS FORCE LOGGING ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 (
    '/u01/app/oracle/oradata/orcl/redo01.log',
    '/u01/app/oracle/oradata/orcl/redo11.log'
  ) SIZE 50M BLOCKSIZE 512,
  GROUP 2 '/u01/app/oracle/oradata/orcl/redo02.log'  SIZE 50M BLOCKSIZE 512,
  GROUP 3 '/u01/app/oracle/oradata/orcl/redo03.log'  SIZE 50M BLOCKSIZE 512
DATAFILE
  '/u01/app/oracle/oradata/orcl/system01.dbf',
  '/u01/app/oracle/oradata/orcl/sysaux01.dbf',
  '/u01/app/oracle/oradata/orcl/undotbs01.dbf',
  '/u01/app/oracle/oradata/orcl/users01.dbf',
  '/home/oracle/backup/test01.tts',
  '/u01/app/oracle/oradata/orcl/assm01.dbf',
  '/u01/app/oracle/oradata/orcl/mssm01.dbf',
  '/u01/app/oracle/oradata/orcl/rc_data01.dbf',
  '/u01/app/oracle/oradata/orcl/ogg01.dbf',
  '/u01/app/oracle/oradata/orcl/yhqt01.dbf'
CHARACTER SET AL32UTF8
;

EXECUTE SYS.DBMS_BACKUP_RESTORE.CFILESETSNAPSHOTNAME('/u01/app/oracle/product/11.2.0/db_1/dbs/snapcf_orcl.f');
VARIABLE RECNO NUMBER;
EXECUTE :RECNO := SYS.DBMS_BACKUP_RESTORE.SETCONFIG('RETENTION POLICY','TO RECOVERY WINDOW OF 7 DAYS');
VARIABLE RECNO NUMBER;
EXECUTE :RECNO := SYS.DBMS_BACKUP_RESTORE.SETCONFIG('CONTROLFILE AUTOBACKUP','ON');
VARIABLE RECNO NUMBER;
EXECUTE :RECNO := SYS.DBMS_BACKUP_RESTORE.SETCONFIG('BACKUP OPTIMIZATION','ON');
VARIABLE RECNO NUMBER;
EXECUTE :RECNO := SYS.DBMS_BACKUP_RESTORE.SETCONFIG('SNAPSHOT CONTROLFILE NAME','TO ''/u01/app/oracle/product/11.2.0/db_1/dbs/snapcf_orcl.f''');
RECOVER DATABASE

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER SYSTEM ARCHIVE LOG ALL;

ALTER DATABASE OPEN;

ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/orcl/temp01.dbf'
     SIZE 61865984  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
View Code

8.3 恢复控制文件

8.3.1 控制文件备份的时间跨度分类

在时间跨度上控制文件备份分3类:在线镜像备份、结构备份和历史备份

--1 在线镜像备份:在线副本,control_files参数指向的除了损坏的控制文件以外的其他健康的控制文件,当前数据库的物理结构,知道最新的检查点、

最新的在线日志序列号、最新的SCN\数据库SCN、控制文件序列号、控制文件SCN、各个数据文件头部检查点信息及归档日志等。

--2 结构备份:该备份中数据库的物理结构信息(数据文件和在线重做日志)和当前控制文件一致,但最新的检查点最新的重做日志序列号、SCN数据库SCN

控制文件序列号控制文件SCN各个数据文件都不检查点归档信息比当前控制文件中的旧。在产生自动备份或手动备份之后,如果数据库的结构没有发生任何变化,

如添加删除表空间、添加删除在线日志,那么它们就是结构备份。

--3 历史备份:该备份数据库的物理结构和当前控制文件不一致(更不用提SCN)。在产生自动或手动备份后,物理结构发生变化,那么它们就是历史备份。

大多数情况,恢复控制文件时先考虑使用在线镜像备份,其次是结构备份最后是历史备份。

除了在线镜像备份意外,利用其它备份恢复的程序顺序3个步骤

--1 从备份中还原控制文件
--2 用重做日志介质恢复数据库(apply log)
--3 以重设日志的方式打开数据库

8.3.2 恢复前的准备

为了恢复控制文件,实例应该处于nomount状态。如果发现问题时实例还未关闭,首先应该用shutdown abort命令关闭,

接着虽然可以使用startup nomount启动,但是建议使用startup启动实例,卡在nomount状态,可以知道很多告警日志和追踪日志中产生更多的有用信息

8.3.3 利用在线镜像备份恢复

若在线镜像备份可用,恢复主要流程如下:

--1 使用startup启动到nomount状态
--2 查看alert log和追踪日志观察损坏的具体情况
--3 用os 系统命令用健康的在线镜像备份替换已损坏或丢失的控制文件
--4 启动到mount状态
--5 启动到open状态
例如:手工修改一个控制文件,然后恢复
[oracle@DSI orcl]$ pwd
/u01/app/oracle/oradata/orcl
[oracle@DSI orcl]$ echo \"database_name:orcl\" > db
[oracle@DSI orcl]$ dd if=db  of=control01.ctl  bs=16834  seek=1 count=1 conv=notrunc
SQL> shutdown immediate;
ORA-00227: corrupt block detected in control file: (block 1, # blocks 1)
ORA-00202: control file: '/u01/app/oracle/oradata/orcl/control01.ctl'
SQL> shutdown abort;
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area  784998400 bytes
Fixed Size            2257352 bytes
Variable Size          511708728 bytes
Database Buffers      264241152 bytes
Redo Buffers            6791168 bytes
ORA-00227: corrupt block detected in control file: (block 0, # blocks )
--可以cp control01.ctl  /tmp/control01.ctl 防止被误删
[oracle@DSI orcl]$ rm control01.ctl 
[oracle@DSI orcl]$ cp control02.ctl control01.ctl ##利用在线镜像进行快速恢复
SQL> startup mount;
ORA-01081: cannot start already-running ORACLE - shut it down first
SQL> alter database mount;
Database altered.
SQL> alter database open;
Database altered.

在线镜像备份即当前备份具有所有的最新信息,所以在恢复的流程中,不需要使用recover,主要依靠操作系统的cp命令。

8.3.4 利用自动备份恢复

若自动备份可用,恢复流程

--1 startup启动到nomount状态
--2 restore controlfile from autobackup还原控制文件
--3 启动到mount状态
--4 recover database恢复数据库
--5 resetlogs打开数据库
SQL> startup;
[oracle@DSI ~]$ rman target
RMAN> restore controlfile from autobackup; ##使用了快速恢复区
RMAN> mount database;
RMAN> recover database; ##自动在快速恢复区内找备份和归档日志、自动找最当前的在线日志、判断控制文件是否需要恢复、读取日志信息以恢复数据文件和控制文件的不行信息。
RMAN> alter database open resetlogs;
SYS@ orcl >show parameter db_recovery
NAME                     TYPE     VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest             string     /u01/app/oracle/fra
db_recovery_file_dest_size         big integer 4G

3recover database命令,分别在sqlplusrman中执行

--1 SQL> recover database; 用来对所有数据文件进行恢复,并且只能使用保存在文件系统上的归档日志及在线日志。使用此命令的前提是控制文件,不可以是还原或重建而来的。

--2 SQL> recover database using backup controlfile用来对所有数据文件及控制文件进行恢复,并且只能使用保存在文件系统上的归档日志和在线日志。

--3 RMAN> recover database; 用来对所有数据文件及控制文件进行恢复,并且可以使用增量备份、备份中的和文件系统上的归档日志,以及文件系统上的在线日志

本例子中最后使用resetlog打开数据库,原因是recover只能修复控制文件中数据库物理结构信息,而无法修改控制文件中的当前重做日志的序列号等信息,

recover执行完成后,控制文件中当前在线日志序列号还是备份是的。若按照alter database open打开,将报错,为了抹去控制文件的这个念头,采用重设日志功能,日志序列号就从1重新开始。

 这里虽然使用了resetlogs,但是recover database成功执行已提交的事务不会丢失,resetlogs仅仅是为了照顾控制文件,与不完全恢复的resetlogs是不同的。

 如果遗漏了recover database步骤,直接执行alter database open resetlogs会报错

ORA-01194: file 1 needs more recovery to be consistent--1号数据文件需要更多恢复。

8.3.5 利用手动备份恢复

利用手动备份恢复流程

--1 启动nomount状态
--2 搜索备份集的位置
--3 用指定备份集路径的restore controlfile from ‘路径’命令还原控制文件或者用操作系统命令把镜像复制到原位
--4 启动到mount状态
--5 recover database恢复数据库
--6 用resetlogs打开数据库

在第三步还原控制文件之前,dba必须确定控制文件备份集的位置,如果使用catalog则不必,否则restore controlfile会报错

#错误示范
RMAN> restore controlfile; ##会报错,rman找不到rman资料库,找不到备份集
RMAN> restore controlfile from autobackup; ##使用自动备份找不到文件
正确姿势
RMAN> restore controlfile from '/home/oracle/backup/20190430_ORCL_6_1_1534031567.ctl';
RMAN> mount database;

查看当前数据库中的控制文件状态和数据文件头状态

SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
       1191079
SQL> select file#,checkpoint_change# from v$datafile;
     FILE# CHECKPOINT_CHANGE#
---------- ------------------
     1          1191079
     2          1191079
     3          1191079
     4          1191079
     5          1191079
SQL> select checkpoint_change# from v$datafile_header;
CHECKPOINT_CHANGE#
------------------
       1191079
       1191079
       1191079
       1191079
       1191079
RMAN> recover database;
RMAN> alter database open resetlogs;

如果使用了rman catalog,在restore controlfile时不需要指定from,也不会报错

RMAN-06563

[oracle@DSI ~]$ rman target sys/***@orcl catalog rcowner/***@orcl
RMAN> run {
startup force nomount;
restore controlfile;
mount database;
recover database;
alter database open resetlogs;
}

8.3.6 利用历史备份恢复

注意,恢复时如果有在线镜像备份或结构备份,历史备份是不需要考虑也是不应该考虑的,因为此时备份和当前数据库物理结构不一致,会带来一定的麻烦

第二类和第三类recover database命令可以自动修复某一些不一致:

--1 备份控制文件中没有某个数据文件和表空间信息,但实际上存在,比如:备份控制文件后,又新建了表空间

--2 备份控制文件中没有某个在线日志组的信息,实际上存在,比如:备份控制文件后,在添加了日子组,并且shutdown abort或实例崩溃时

新添加的那个日志组可以是currentactive状态,这种情况下,recover database命令将直接以控制文件中的信息为准,结果是恢复时就当新添加的日志组不存在过一样,恢复过程中没有阻碍。

--3 备份控制文件中有某个在线日志组信息,但实际上不存在,比如:备份控制文件后,再删除日志组,这种情况下以控制文件中的信息为准,

结果是恢复时删除的日志组将复活,也就是又被创建回来,恢复过程没有任务阻碍。

而另一些不一致不能依赖recover database命令自动修复,恢复过程需要人为干预,只能使用第二类recover database或特殊的recover命令才能恢复。

具体如下:

--1 备份控制文件中具有某个数据文件或表空间信息,但实际上不存在,比如:备份控制文件后,再删除表空间,

需要SQL> recover database using backup controlfile或者 recover database skip tablespace命令才能修复

--2 备份中没有某个在线日志组,但实际上存在,比如:备份控制文件之后在添加新日志组,并且新添加的日志组刚好是在shutdown abort

实例崩溃时的currentactive状态的日志组,那么在RMAN执行recover database时就会报错RMAN-06054: media recovery requesting unknown archived log

请求未知归档的错误,需要使用SQL> recover database using backup controlfile命令,手动指定重做日志的路径才能完成恢复。

SQL> RECOVER DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL;

SQL> ALTER DATABASE OPEN RESETLOGS;

--1 自动修复不一致

场景1:控制文件自动备份功能关闭,在备份了控制文件之后,dba创建了一个test01表空间,在备份中这个表空间并不存在,

及物理结构与当前不一致,备份就此成了一个历史备份。目前状态时所有在线控制文件损坏,无在线镜像备份和自动备份可用

首先还原控制文件

RMAN> restore controlfile from ‘/u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp’;
还原结束后启动到mount状态
RMAN> mount database;
观察还原出来的控制文件,查看datafile是否有新建的test01表空间,答案是否定的
SQL> select name from v$datafile;
然后用第三类recover database恢复
RMAN> recover database;
再次查询
SQL> select name from v$datafile;
RMAN> alter database open resetlogs;

--简单记录,详细点击查看

SYS@ orcl >create tablespace test01 datafile '/u01/app/oracle/oradata/orcl/test011.dbf' size 10m autoextend on;
SYS@ orcl >shutdown abort;
[oracle@DSI orcl]$ mv control01.ctl c1.ctl
[oracle@DSI orcl]$ mv control02.ctl c2.ctl
[oracle@DSI ~]$ rman target /
RMAN> startup;
Oracle instance started
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of startup command at 07/17/2019 15:49:37
ORA-00205: error in identifying control file, check alert log for more info
RMAN> restore controlfile from '/u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp';
RMAN> mount database;
SQL> select name from v$datafile;
RMAN> recover database;
SQL> select name from v$datafile;
RMAN> alter database open resetlogs;
查看控制文件
[oracle@DSI orcl]$ ll control0*
-rw-r----- 1 oracle oinstall 10076160 Jul 17 16:03 control01.ctl
-rw-r----- 1 oracle oinstall 10076160 Jul 17 16:03 control02.ctl
--手动备份自动修复
1308    Full    9.67M      DISK        00:00:00     17-JUL-19      
        BP Key: 1310   Status: AVAILABLE  Compressed: NO  Tag: TAG20190717T103718
        Piece Name: /u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp
  Control File Included: Ckp SCN: 10509720     Ckp time: 17-JUL-19

SYS@ orcl >create tablespace test01 datafile '/u01/app/oracle/oradata/orcl/test011.dbf' size 10m autoextend on;
Tablespace created.
SYS@ orcl >shutdown abort;
ORACLE instance shut down.
[oracle@DSI orcl]$ mv control01.ctl c1.ctl
[oracle@DSI orcl]$ mv control02.ctl c2.ctl

[oracle@DSI ~]$ rman target /

Recovery Manager: Release 11.2.0.4.0 - Production on Wed Jul 17 15:47:54 2019

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

connected to target database (not started)

RMAN> startup;

Oracle instance started
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of startup command at 07/17/2019 15:49:37
ORA-00205: error in identifying control file, check alert log for more info
RMAN> restore controlfile from '/u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp';

Starting restore at 17-JUL-19
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=135 device type=DISK

channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/u01/app/oracle/oradata/orcl/control01.ctl
output file name=/u01/app/oracle/oradata/orcl/control02.ctl
Finished restore at 17-JUL-19

RMAN> mount database;

database mounted
released channel: ORA_DISK_1
SQL> select name from v$datafile;

NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf
/u01/app/oracle/oradata/orcl/sysaux01.dbf
/u01/app/oracle/oradata/orcl/undotbs01.dbf
/u01/app/oracle/oradata/orcl/users01.dbf
/home/oracle/backup/test01.tts
/u01/app/oracle/oradata/orcl/assm01.dbf
/u01/app/oracle/oradata/orcl/mssm01.dbf
/u01/app/oracle/oradata/orcl/rc_data01.dbf
/u01/app/oracle/oradata/orcl/ogg01.dbf
/u01/app/oracle/oradata/orcl/yhqt01.dbf

10 rows selected.
RMAN> recover database;

Starting recover at 17-JUL-19
Starting implicit crosscheck backup at 17-JUL-19
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=10 device type=DISK
Crosschecked 5 objects
Finished implicit crosscheck backup at 17-JUL-19

Starting implicit crosscheck copy at 17-JUL-19
using channel ORA_DISK_1
Finished implicit crosscheck copy at 17-JUL-19

searching for all files in the recovery area
cataloging files...
cataloging done

List of Cataloged Files
=======================
File Name: /u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp
File Name: /u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855997_glx2mxy4_.bkp

using channel ORA_DISK_1

starting media recovery

archived log for thread 1 with sequence 50 is already on disk as file /u01/app/oracle/oradata/orcl/redo02.log
archived log file name=/u01/app/oracle/oradata/orcl/redo02.log thread=1 sequence=50
creating datafile file number=11 name=/u01/app/oracle/oradata/orcl/test011.dbf
archived log file name=/u01/app/oracle/oradata/orcl/redo02.log thread=1 sequence=50
media recovery complete, elapsed time: 00:00:01
Finished recover at 17-JUL-19

SQL> /

NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf
/u01/app/oracle/oradata/orcl/sysaux01.dbf
/u01/app/oracle/oradata/orcl/undotbs01.dbf
/u01/app/oracle/oradata/orcl/users01.dbf
/home/oracle/backup/test01.tts
/u01/app/oracle/oradata/orcl/assm01.dbf
/u01/app/oracle/oradata/orcl/mssm01.dbf
/u01/app/oracle/oradata/orcl/rc_data01.dbf
/u01/app/oracle/oradata/orcl/ogg01.dbf
/u01/app/oracle/oradata/orcl/yhqt01.dbf
/u01/app/oracle/oradata/orcl/test011.dbf

11 rows selected.

RMAN> alter database open resetlogs;

database opened
[oracle@DSI orcl]$ ll control0*
-rw-r----- 1 oracle oinstall 10076160 Jul 17 16:03 control01.ctl
-rw-r----- 1 oracle oinstall 10076160 Jul 17 16:03 control02.ctl
View Code

--2 手动修复不一致

场景1:控制文件自动备份关闭,在备份了控制文件后,dba删除了一个test01表空间,在备份中这个表空间及数据文件还是存在的,

目前的状况是所有控制文件损坏,无在线镜像备份和自动备份可用。

首先还原控制文件

RMAN> restore controlfile from '/u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp';
RMAN> mount database;
SQL> select name from v$datafile; ##查看被删除的数据文件是否在存在
RMAN> recover database; ##此时会报错 RMAN-06094:datafile 11 must be restored
SQL> alter database datafile 11 offline; ##使该数据文件下线
SQL> alter database using backup controlfile; ##使用该命令恢复数据库,并在提示出现后输入AUTO。注意L这可能在最后阶段报错ORA-27037和ORA-00308,意思是找不到某个归档日志,如果归档日志并没有丢失或损坏,在sqlplus中找还没有来得及归档的在线日志。
根据提示,输入相应的在线重做日志
SQL> alter database using backup controlfile; ##如果dba不知道那个日志,随便输入任意在线重做日志,不是的话还是会报错,不会用用错的危险,在恢复途中使用的重做日志中一定有关于删除test01表空间的记录。
SQL> select name from v$datafile;
实际上,解决这个问题还可以采用一个更简单的方法,在recover database时候使用skip tablespace跳过test01表空间,比如
RMAN> recover database skip tablespace test01;
注意,此时使用skip tablespace只能精确到表空间内所有的数据文件,前者可以精确到某一个数据文件
RMAN> alter database open resetlogs; ##最后resetlogs打开数据库
--测试
RMAN> backup as backupset current controlfile;
SQL> drop tablespace test01;
SQL> select name from v$datafile;
[oracle@DSI orcl]$ mv control02.ctl c2.ctl
[oracle@DSI orcl]$ mv control01.ctl c1.ctl
[oracle@DSI orcl]$ ll control0*
[oracle@DSI ~]$ rman target /
RMAN>  startup;
RMAN> restore controlfile from '/u01/app/oracle/fra/ORCL/backupset/2019_07_17/o1_mf_ncnnf_TAG20190717T161208_glxp2spk_.bkp';
RMAN> mount database;
SQL> select name from v$datafile;
RMAN> recover database;
RMAN> alter database open resetlogs;

详细点击查看

--手动备份手动修复
RMAN> backup as backupset current controlfile;

Starting backup at 17-JUL-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
including current control file in backup set
channel ORA_DISK_1: starting piece 1 at 17-JUL-19
channel ORA_DISK_1: finished piece 1 at 17-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/backupset/2019_07_17/o1_mf_ncnnf_TAG20190717T161208_glxp2spk_.bkp tag=TAG20190717T161208 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 17-JUL-19
SQL> drop tablespace test01;

Tablespace dropped.

SQL> select name from v$datafile; 

NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf
/u01/app/oracle/oradata/orcl/sysaux01.dbf
/u01/app/oracle/oradata/orcl/undotbs01.dbf
/u01/app/oracle/oradata/orcl/users01.dbf
/home/oracle/backup/test01.tts
/u01/app/oracle/oradata/orcl/assm01.dbf
/u01/app/oracle/oradata/orcl/mssm01.dbf
/u01/app/oracle/oradata/orcl/rc_data01.dbf
/u01/app/oracle/oradata/orcl/ogg01.dbf
/u01/app/oracle/oradata/orcl/yhqt01.dbf

10 rows selected.
[oracle@DSI orcl]$ mv control02.ctl c2.ctl
[oracle@DSI orcl]$ mv control01.ctl c1.ctl
[oracle@DSI orcl]$ ll control0*
ls: cannot access control0*: No such file or directory
[oracle@DSI ~]$ rman target /

Recovery Manager: Release 11.2.0.4.0 - Production on Wed Jul 17 16:14:32 2019

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

connected to target database (not started)

RMAN>  startup;

Oracle instance started
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of startup command at 07/17/2019 16:14:44
ORA-00205: error in identifying control file, check alert log for more info

RMAN> restore controlfile from '/u01/app/oracle/fra/ORCL/backupset/2019_07_17/o1_mf_ncnnf_TAG20190717T161208_glxp2spk_.bkp';

Starting restore at 17-JUL-19
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=135 device type=DISK

channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/u01/app/oracle/oradata/orcl/control01.ctl
output file name=/u01/app/oracle/oradata/orcl/control02.ctl
Finished restore at 17-JUL-19
RMAN> mount database;

database mounted
released channel: ORA_DISK_1
SQL> select name from v$datafile;

NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf
/u01/app/oracle/oradata/orcl/sysaux01.dbf
/u01/app/oracle/oradata/orcl/undotbs01.dbf
/u01/app/oracle/oradata/orcl/users01.dbf
/home/oracle/backup/test01.tts
/u01/app/oracle/oradata/orcl/assm01.dbf
/u01/app/oracle/oradata/orcl/mssm01.dbf
/u01/app/oracle/oradata/orcl/rc_data01.dbf
/u01/app/oracle/oradata/orcl/ogg01.dbf
/u01/app/oracle/oradata/orcl/yhqt01.dbf
/u01/app/oracle/oradata/orcl/test011.dbf

11 rows selected.
RMAN> recover database;

Starting recover at 17-JUL-19
Starting implicit crosscheck backup at 17-JUL-19
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=135 device type=DISK
Crosschecked 6 objects
Finished implicit crosscheck backup at 17-JUL-19

Starting implicit crosscheck copy at 17-JUL-19
using channel ORA_DISK_1
Finished implicit crosscheck copy at 17-JUL-19

searching for all files in the recovery area
cataloging files...
cataloging done

List of Cataloged Files
=======================
File Name: /u01/app/oracle/fra/ORCL/backupset/2019_07_17/o1_mf_ncnnf_TAG20190717T161208_glxp2spk_.bkp
File Name: /u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013875930_glxp2ts0_.bkp
File Name: /u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855838_glx2gy3s_.bkp
File Name: /u01/app/oracle/fra/ORCL/autobackup/2019_07_17/o1_mf_s_1013855997_glx2mxy4_.bkp

using channel ORA_DISK_1

starting media recovery

archived log for thread 1 with sequence 1 is already on disk as file /u01/app/oracle/oradata/orcl/redo01.log
archived log file name=/u01/app/oracle/oradata/orcl/redo01.log thread=1 sequence=1
media recovery complete, elapsed time: 00:00:00
Finished recover at 17-JUL-19
SQL> /

NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf
/u01/app/oracle/oradata/orcl/sysaux01.dbf
/u01/app/oracle/oradata/orcl/undotbs01.dbf
/u01/app/oracle/oradata/orcl/users01.dbf
/home/oracle/backup/test01.tts
/u01/app/oracle/oradata/orcl/assm01.dbf
/u01/app/oracle/oradata/orcl/mssm01.dbf
/u01/app/oracle/oradata/orcl/rc_data01.dbf
/u01/app/oracle/oradata/orcl/ogg01.dbf
/u01/app/oracle/oradata/orcl/yhqt01.dbf

10 rows selected.

RMAN> alter database open;

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of alter db command at 07/17/2019 16:17:27
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open

RMAN> alter database open resetlogs;

database opened
View Code

这里测试与实际的有点差异,就是使用了存在快速恢复区里的多个控制文件的备份

8.3.7 缺少归档日志情况下的恢复

在恢复控制文件时recover database命令需要使用归档日志,所谓归档缺少就是指控制文件从备份还原后,在执行recover database命令时找不到相应的日志导致恢复终止的情况。

SQL> recover database until cancel;
ORA-00279: change 9793080 generated at 06/06/2019 15:42:14 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fra/ORCL/archivelog/2019_06_06/o1_mf_1_32_%u_.arc
ORA-00280: change 9793080 for thread 1 is in sequence #32

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

ORA-00308: cannot open archived log
'/u01/app/oracle/fra/ORCL/archivelog/2019_06_06/o1_mf_1_32_%u_.arc'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3

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: '/u01/app/oracle/oradata/orcl/system01.dbf'

这种情况下的恢复主要流程:

--1 首先还原控制文件,方式不限
--2 执行recover database报错RMAN-06054,找不到某归档
--3 查看相关动态性能事务,对问题定性,确认问题与控制文件,而不是与数据文件相关
--4 利用create controlfile重建控制文件
--5 再次执行recover database,还会报RMAN-06054错误,这次是找不到另外一个归档日志
--6 查看v$log视图确定第5步中索要的日志
--7 在sqlplus中执行recover database using backup controlfile等specify log提示符出现后给出正确的在线日志路径,直到命令成功结束
--8 以resetlog命令打开数据库
--9 添加temp临时表空间
--10 将控制文件内其他丢失的信息用catalog和configure添加回去。

可以参考dsi系列的控制文件的相关恢复

8.4 noresetlogs收尾

前面的恢复操作都是使用alter database open resetlogs进行打开数据库

其实不使用resetlogs打开也是可以的,关键方法是首先让recover database命令成功完成,然后再重新创建一个控制文件,并在创建的命令中使用noresetlogs关键字

主要步骤:

--1 首先必须完成控制文件和数据库的恢复(不可以是不完全恢复,因为不完全恢复无法摆脱resetlogs的命运)
--2 在将要使用resetlogs打开数据库之前,执行alter database backup controlfile to trace 将恢复后的控制文件备份为追踪文件
--3 重启实例到nomount状态
--4 用追踪文件中的noresetlogs版本的create controlfile命令重新创建控制文件并进入mount状态
--5 直接使用alter database open打开数据库,如果遇到ORA-01113错误,先执行recover database命令,在打开数据库
--6 创建temp临时表空间
--7 将控制文件内丢失的其他信息补回,比如configure等

有关控制文件与只读数据文件同时损坏的情况的恢复请参考之后的章节

有关控制文库无备份的情况下的恢复请参考之前的dsi系列或之后的章节

如果参数文件和控制文件同时损坏,必须先恢复参数文件,并至少留意参数文件中几个会影响控制文件恢复的参数

--db_recovery_file_dest

--db_namedb_unique_name(默认和db_name一样)

决定备份和归档日志默认的搜索路径;

--control_files确定restore controlfile的默认目的地,必要时可以先修改这些参数后再还原控制文件

posted @ 2019-07-17 17:17  春困秋乏夏打盹  阅读(5042)  评论(0编辑  收藏  举报