ablog

不器用で落着きのない技術者のメモ

制御ファイル障害からのリカバリ手順

Oracle Database で制御ファイルに障害が発生した場合のリカバリ手順をまとめてみた。
以下の方法でリカバリすることができる。

  • 一部の制御ファイルに障害が発生したケース
    • 正常な制御ファイルをコピーする
  • 全ての制御ファイルに障害が発生したケース
    • バックアップ制御ファイルをリストアする
    • 制御ファイルを再作成する

また、元の場所に制御ファイルをリストアまたは再作成できない場合は「補足」を参照。

一部の制御ファイルに障害が発生したケース

正常な制御ファイルをコピーする
  • リスナーを停止する。
$ lsnrctl stop
  • インスタンスを停止する。
    • 1つでも制御ファイルが破損したらインスタンスは停止するが、停止していない場合は shutdown abort で停止する。
$ sqlplus / as sysdba
SQL> shutdown abort
SQL> exit
  • 正常な制御ファイルを破損した制御ファイルに上書きコピーする。
$ cp /u01/app/oracle/oradata/orcl/control01.ctl /u01/app/oracle/oradata/orcl/control03.ctl
$ sqlplus / as sysdba
SQL> startup
SQL> exit
  • リスナーを起動する。
$ lsnrctl start

全ての制御ファイルに障害が発生したケース

バックアップ制御ファイルをリストアする
  • リスナーを停止する。
$ lsnrctl stop
  • インスタンスを停止する。
    • 1つでも制御ファイルが破損したらインスタンスは停止するが、停止していない場合は shutdown abort で停止する。
$ sqlplus / as sysdba
SQL> shutdown abort
SQL> exit
  • バックアップ制御ファイルをリストアする。
$ cd /u01/app/oracle/oradata/orcl
# 「/home/oracle/control.ctl」はあらかじめ「alter database backup controlfile to ...」で取得しておいたバックアップ
$ cp /home/oracle/control.ctl control01.ctl
$ cp /home/oracle/control.ctl control02.ctl
$ cp /home/oracle/control.ctl control03.ctl
  • データベースをマウントする。
$ sqlplus / as sysdba
SQL> startup mount
SQL> recover database using backup controlfile until cancel;
ORA-00279: change 169050 generated at 01/07/2010 08:49:45 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/product/10.2.0/db_1/dbs/arch1_5_699805707.dbf
ORA-00280: change 169050 for thread 1 is in sequence #5


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

--オンラインREDOログの名前を指定し、[Enter]を押す(正しいログが見つかるまで繰り返す)。
/u01/app/oracle/oradata/orcl/redo03.log    <-- 1回目
ORA-00310: archived log contains sequence 3; sequence 5 required
ORA-00334: archived log: '/u01/app/oracle/oradata/orcl/redo03.log'


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'


SQL> recover database using backup controlfile until cancel;
ORA-00279: change 169050 generated at 01/07/2010 08:49:45 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/product/10.2.0/db_1/dbs/arch1_5_699805707.dbf
ORA-00280: change 169050 for thread 1 is in sequence #5


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u01/app/oracle/oradata/orcl/redo01.log <-- 2回目
ORA-00310: archived log contains sequence 4; sequence 5 required
ORA-00334: archived log: '/u01/app/oracle/oradata/orcl/redo01.log'


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'


SQL> recover database using backup controlfile until cancel;
ORA-00279: change 169050 generated at 01/07/2010 08:49:45 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/product/10.2.0/db_1/dbs/arch1_5_699805707.dbf
ORA-00280: change 169050 for thread 1 is in sequence #5


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u01/app/oracle/oradata/orcl/redo02.log <-- 3回目
Log applied.
Media recovery complete. <-- 正しいログが見つかるとこのメッセージが表示される
  • データベースをオープンする。
SQL> alter database open resetlogs;
  • リスナーを起動する。
$ lsnrctl start
制御ファイルを再作成する
  • リスナーを停止する。
$ lsnrctl stop
  • インスタンスを停止する。
    • 1つでも制御ファイルが破損したらインスタンスは停止するが、停止していない場合は shutdown abort で停止する。
$ sqlplus / as sysdba
SQL> shutdown abort
SQL> exit
$ cd /home/oracle
# 「control.trc」はあらかじめ「alter database backup controlfile to trace as ...」で取得しておいた論理バックアップ
$ cp control.trc create_controlfile.sql 
# 「Set #1. NORESETLOGS case」の「STARTUP NOMOUNT 〜 -- End of tempfile additions.;」以外の行を削除する
$ vi create_controlfile.sql 
$ cat create_controlfile.sql 
STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 5
    MAXLOGMEMBERS 5
    MAXDATAFILES 100
    MAXINSTANCES 1
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 (
    '/u01/app/oracle/oradata/orcl/redo01.log',
    '/u01/app/oracle/oradata/orcl/redo11.log'
  ) SIZE 100M,
  GROUP 2 (
    '/u01/app/oracle/oradata/orcl/redo02.log',
    '/u01/app/oracle/oradata/orcl/redo12.log'
  ) SIZE 100M,
  GROUP 3 (
    '/u01/app/oracle/oradata/orcl/redo03.log',
    '/u01/app/oracle/oradata/orcl/redo13.log'
  ) SIZE 100M,
  GROUP 4 (
    '/u01/app/oracle/oradata/orcl/redo04.log',
    '/u01/app/oracle/oradata/orcl/redo14.log'
  ) SIZE 10M
DATAFILE
  '/u01/app/oracle/oradata/orcl/system01.dbf',
  '/u01/app/oracle/oradata/orcl/undotbs01.dbf',
  '/u01/app/oracle/oradata/orcl/sysaux01.dbf',
  '/u01/app/oracle/oradata/orcl/user01.dbf'
CHARACTER SET JA16EUC
;

-- Commands to re-create incarnation table
-- Below log names MUST be changed to existing filenames on
-- disk. Any one log file from each branch can be used to
-- re-create incarnation records.
-- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/product/10.2.0/db_1/dbs/arch1_1_699805707.dbf';
-- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/product/10.2.0/db_1/dbs/arch1_1_707648733.dbf';
-- Recovery is required if any of the datafiles are restored backups,
-- or if the last shutdown was not normal or immediate.
RECOVER DATABASE

-- All logs need archiving and a log switch is needed.
ALTER SYSTEM ARCHIVE LOG ALL;

-- Database can now be opened normally.
ALTER DATABASE OPEN;

-- Commands to add tempfiles to temporary tablespaces.
-- Online tempfiles have complete space information.
-- Other tempfiles may require adjustment.
ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/orcl/temp01.dbf'
     SIZE 20971520  REUSE AUTOEXTEND ON NEXT 8192  MAXSIZE 32767M;
-- End of tempfile additions.
  • 制御ファイルを再作成して、データベースをオープンする。
$ sqlplus / as sysdba
SQL> @create_controlfile.sql
ORACLE instance started.

Total System Global Area  184549376 bytes
Fixed Size                  1266488 bytes
Variable Size             130026696 bytes
Database Buffers           50331648 bytes
Redo Buffers                2924544 bytes
Database mounted.

Control file created.

Media recovery complete.

System altered.

Database altered.

Tablespace altered.

補足

  • 元の場所に制御ファイルをリストアできない場合は、制御ファイルのリストアまたは再作成の前に以下の手順で spfile 内の制御ファイルのパスを変更してやる。
$ sqlplus / as sysdba
SQL> create pfile='?/dbs/initorcl_20100105.org' from spfile;
SQL> exit
$ cd $ORACLE_HOME/dbs
$ cp initorcl_20100105.org initorcl_20100105.mod
$ vi initorcl_20100105.mod
*.control_files=' /u02/app/oracle/oradata/orcl',' /u03/app/oracle/oradata/orcl'
$ sqlplus / as sysdba
--spfile のパスをデフォルトから変更している場合、「spfile='...'」とパスを指定する。しないと $ORACLE_HOME/dbs の下に spfile が作成される。
SQL> create spfile='/u01/app/oracle/admin/orcl/pfile/spfileorcl.ora' from pfile='?/dbs/initorcl_20100105.mod';
  • バックアップ制御ファイルをリストアするケースでは、初期化パラメータ log_archive_format に「%r」を含めていないなら復旧後にバックアップを取得する必要がある。以前のバックアップが使用できなくなるため。

resetlogs オプションを付けて recover database を実行した後、すぐにバックアップを取って下さい! データベースをシャットダウンした後のコールドバックアップが最良ですが、どうしても必要な場合はホットバックアップを実行して下さい。ただしその場合には次のようなリスクがあることを認識して下さい。

Oracle データベースの復旧手順
  • この手順を検証した環境は以下の通り。
$ uname -a
Linux centos51 2.6.18-128.el5 #1 SMP Wed Jan 21 10:44:23 EST 2009 i686 i686 i386 GNU/Linux
$ echo 'select * from v$version;'|sqlplus / as sysdba 
...
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production