数据库在运行过程当中,可能会处于某种原因导致控制文件丢失或者损坏,数据库文件记录着数据库的结构信息,包括数据文件,归档日志文件等数据库的重要信息,控制文件丢失,直接会导致数据库宕机。这篇博客会模拟各种控制文件丢失的情况,来恢复数据库的正常使用。
丢失部分控制文件
控制文件在数据库中占据着非常主要的地位,通常会采用多路复用的原则对数据库控制文件进行保护,即使丢失了部分控制文件,数据库可以通过多路复用中的其他控制文件,恢复控制文件。
假设数据库中我们控制文件存放在两个位置
位置1:/u01/app/oracle/oradata/XE/control.ctl
位置2:/u02/app/oracle/oradata/XE/control.ctl
SQL> select name from v$controlfile; NAME -------------------------------------------------- /u01/app/oracle/oradata/XE/control.ctl /u02/app/oracle/oradata/XE/control.ctl SQL>
恢复控制文件到默认的目录下
数据库在运行的某个阶段,突然导致/u01目录下的控制文件丢失了,我们希望通过/u02目录下的控制文件来恢复/u01下的控制文件,下面模拟恢复的过程:
rm -rf /u01/app/oracle/oradata/XE/control.ctl
强制停止数据库
SQL> shutdown abort;
拷贝/u02下的控制文件到/u01下控制文件的存放位置
oracle@oracledb:~$ cp /u02/app/oracle/oradata/XE/control.ctl /u01/app/oracle/oradata/XE/
启动数据库
SQL> startup nomount; ORACLE instance started. Total System Global Area 601272320 bytes Fixed Size 2228848 bytes Variable Size 180358544 bytes Database Buffers 415236096 bytes Redo Buffers 3448832 bytes SQL> alter database mount; Database altered. SQL> alter database open; Database altered.
恢复控制文件到其他的目录
假设系统咋运行的过程当中导致存放多路复用的一个控制文件的目录丢失,我们需要把控制文件恢复到别的目录下,这就需要我们修改参数文件中控制文件的路径。下面演示过程:
rm -rf /u01/app/oracle/oradata/XE
强制停止数据库
SQL> shutdown abort; ORACLE instance shut down.
创建控制文件的恢复目录,并拷贝控制文件
root@oracledb:~# mkdir -p /u03/app/oracle/oradata/XE/ root@oracledb:~# chown -R oracle:dba /u03 root@oracledb:~# chmod -R 755 /u03 root@oracledb:~# su - oracle oracle@oracledb:~$ cp /u01/app/oracle/oradata/XE/control.ctl /u03/app/oracle/oradata/XE/
修改参数文件中控制文件的路径
SQL> create pfile from spfile; File created. SQL> host vi $/dbs/initXE.ora SQL> host vi $ORACLE_HOME/dbs/initXE.ora *.control_files='/u01/app/oracle/oradata/XE/control.ctl','/u03/app/oracle/oradata/XE/control.ctl'
重启数据库
SQL> startup nomount pfile=?/dbs/initXE.ora ORACLE instance started. Total System Global Area 601272320 bytes Fixed Size 2228848 bytes Variable Size 180358544 bytes Database Buffers 415236096 bytes Redo Buffers 3448832 bytes SQL> create spfile from pfile; SQL> alter database mount; Database altered. SQL> alter database open; Database altered.
控制文件全部丢失,但是有一个曾经备份过的二进制控制文件
这种情景是数据库在运行的过程当中,控制文件丢失,但以前冷备过一个控制文件,oracle的一致性状态,控制文件的头部和数据库文件的头部有SCN号,来保证数据库文件的一致性。我们使用以前备份过的控制文件需要一些额外的恢复操作,下面演示恢复步骤。
oracle@oracledb:~$ rm -rf /u01/app/oracle/oradata/XE/control.ctl oracle@oracledb:~$ rm -rf /u02/app/oracle/oradata/XE/control.ctl
强制关闭数据库
SQL> shutdown abort; ORACLE instance shut down.
拷贝老的备份的控制文件
oracle@oracledb:~$ cp /upload/control.ctl /u01/app/oracle/oradata/XE/ oracle@oracledb:~$ cp /upload/control.ctl /u02/app/oracle/oradata/XE/
数据库打开到mount状态
SQL> startup mount; ORACLE instance started. Total System Global Area 601272320 bytes Fixed Size 2228848 bytes Variable Size 180358544 bytes Database Buffers 415236096 bytes Redo Buffers 3448832 bytes Database mounted.
数据库在mount时,并不会提示什么错误信息,接下来我们尝试打开数据库,会提示错误。
SQL> alter database open; alter database open * ERROR at line 1: ORA-01190: control file or data file 1 is from before the last RESETLOGS ORA-01110: data file 1: '/u01/app/oracle/oradata/XE/system.dbf'
恢复数据库
我们使用的是一个老的控制文件,在恢复数据库时需要使用using backup controlfile子句。
恢复的过程当中,数据库会提示我们使用归档日志文件来恢复数据库。如果数据库处于非归档模式的情况下,我们只能使用在线重做日志文件来恢复数据库
SQL> recover database using backup controlfile until cancel; ORA-00279: change 458993 generated at 03/31/2018 06:52:10 needed for thread 1 ORA-00289: suggestion : /u01/app/oracle/fast_recovery_area/XE/archivelog/2018_03_31/o1_mf_1_5_%u_.arc ORA-00280: change 458993 for thread 1 is in sequence #5 Specify log: {<RET>=suggested | filename | AUTO | CANCEL} /u01/app/oracle/oradata/XE/redo1.log Log applied. Media recovery complete.
打开数据库
SQL> alter database open resetlogs; Database altered.
控制文件全部丢失,重建控制文件
如果控制文件没有多虑复用,存在单点故障的问题,控制文件一旦丢失,没有备份,我们需要重建控制文件.重建控制文件的sql语句,我们可以通过alert_sid日志中找到。但可能存在一些问题,需要我们注意的:如果找到一个最古老的的控制文件,在这个控制文件创建之后,又新建了表空间,我们需要找到这些表空间,并把表空间的信息加入到重建控制文件中的sql语句中。
oracle@oracledb:~$ rm -rf /u01/app/oracle/oradata/XE/control.ctl oracle@oracledb:~$ rm -rf /u03/app/oracle/oradata/XE/control.ctl
强制停止数据库
SQL> shutdown abort; ORACLE instance shut down.
将数据库打开到nomount状态
SQL> startup nomount ORACLE instance started. Total System Global Area 601272320 bytes Fixed Size 2228848 bytes Variable Size 180358544 bytes Database Buffers 415236096 bytes Redo Buffers 3448832 bytes
create controlfile语句可以在数据库的alert日志文件中找到,我的日志文件位于: /u01/app/oracle/diag/rdbms/xe/XE/trace/alert_XE.log.
或者以前以文本形式备份过的控制文件:
SQL> alter database backup controlfile to trace as '/upload/control1.bak';
下面这个语句是在线重做日志文件和归档日志文件都可用的情况下使用,注意参数NORESETLOGS NOARCHIVELOG和DATAFILE,需要补充后来新建的表空间文件.
CREATE CONTROLFILE REUSE DATABASE "XE" NORESETLOGS NOARCHIVELOG MAXLOGFILES 16 MAXLOGMEMBERS 3 MAXDATAFILES 100 MAXINSTANCES 8 MAXLOGHISTORY 292 LOGFILE GROUP 1 '/u01/app/oracle/oradata/XE/redo1.log' SIZE 50M BLOCKSIZE 512, GROUP 2 '/u01/app/oracle/oradata/XE/redo2.log' SIZE 50M BLOCKSIZE 512 -- STANDBY LOGFILE DATAFILE '/u01/app/oracle/oradata/XE/system.dbf', '/u01/app/oracle/oradata/XE/sysaux.dbf', '/u01/app/oracle/oradata/XE/undotbs1.dbf', '/u01/app/oracle/oradata/XE/users.dbf', '/u01/app/oracle/oradata/XE/itreasury1.dbf' CHARACTER SET AL32UTF8;
recover数据库
SQL> recover database; Media recovery complete.
启动数据库
SQL> alter database open; Database altered.