ablog

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

Oracleデータベースの制御ファイルのみ全損した場合のリカバリ方法を検証してみる

[まとめ]
制御ファイルを全損した場合、以下の2つのリカバリ方法がある。

  1. 物理バックアップ*1を使ったリカバリ
  2. 論理バックアップ*2を使ったリカバリ

いずれの方法でも障害発生直前までリカバリできる。つまり、オンラインREDOログの最後のcommit済みREDOエントリまでリカバリすることができる。

物理バックアップからリカバリする場合、リセットログが必要なためインカネーション番号がカウントアップされるが、10g以降であれば LOG_ARCHIVE_FORMAT にリセットログID(%r)を含めておけば、リセットログ後に障害は発生してもリセットログ以前のバックアップとアーカイブログで障害直前の時点までリカバリすることができる。
逆に{9i以前}または{10g以降で LOG_ARCHIVE_FORMAT にリセットログID(%r)を含めていない}場合で、物理バックアップからリカバリしてリセットログを行った場合はリカバリ後にバックアップを取得しないと障害発生時に復旧できなくなってしまう。

まとめると、2つのリカバリ方法の差異は物理バックアップからのリカバリの場合はリセットログが必要という一点のみ*3。いずれの場合もオンラインREDOログの最新のエントリまでリカバリできる。たいした差はない。あと、論理バックアップをとってなくても、作れば済む気がする。CREATE CONTROFILE 文を実行すれば良いのだから。とっておいたほうがベターだけど。


[検証ポイント]

  • 物理バックアップを使ったリカバリ
    • resetlogs が必要であること。
    • 障害発生前の最後の変更*4が反映されていること。
  • 論理バックアップを使ったリカバリ
    • resetlogs は不要であること。
    • 障害発生前の最後の変更*5が反映されていること。


[テストシナリオ1(物理バックアップ使用)]

  • 制御ファイルの物理バックアップを取得する。
$ sqlplus / as sysdba
SQL> alter database backup controlfile to '/export/home/oracle/oradata/orcl/control.bak';
  • ログスイッチする。
SQL> alter system archive log current;
SQL> select * from v$log;
    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIV STATUS                           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- ------ -------------------------------- ------------- ------------
         1          1         61   52428800          1 YES    INACTIVE                               1227709 10-JUN-09
         2          1         62   52428800          1 YES    ACTIVE                                 1259238 27-JUN-09
         3          1         63   52428800          1 NO     CURRENT                                1280213 20-JUL-09
SQL> archive log list
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /export/home/oracle/arch01/orcl
Oldest online log sequence     61
Next log sequence to archive   63
Current log sequence           63
  • データを更新してcommitする。
SQL> conn scott/tiger
SQL> select name from emp;

NAME
--------------------
neo

SQL> insert into emp(id, name) values ('01', 'smith');
SQL> commit;
SQL> select name from emp;

NAME
--------------------
neo
smith
SQL> exit
  • 全ての制御ファイルを削除する。
$ rm $ORACLE_BASE/oradata/orcl/*.ctl
$ sqlplus / as sysdba
SQL> shutdown abort
ORACLE instance shut down.
SQL> exit
  • バックアップ制御ファイルをリストアする。
$ cd $ORACLE_BASE/oradata/orcl
$ cp control.bak ./control01.ctl
$ cp control.bak ./control02.ctl
$ cp control.bak ./control03.ctl
  • REDOログを適用する。
$ sqlplus / as sysdba
SQL> startup  mount
SQL> recover database until cancel using backup controlfile;
ORA-00279: change 1279885 generated at 07/20/2009 00:17:53 needed for thread 1
ORA-00289: suggestion : /export/home/oracle/arch01/orcl/1_62_675478271.dbf
ORA-00280: change 1279885 for thread 1 is in sequence #62


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/export/home/oracle/oradata/orcl/redo02.log
ORA-00279: change 1280213 generated at 07/20/2009 00:19:48 needed for thread 1
ORA-00289: suggestion : /export/home/oracle/arch01/orcl/1_63_675478271.dbf
ORA-00280: change 1280213 for thread 1 is in sequence #63
ORA-00278: log file '/export/home/oracle/oradata/orcl/redo02.log' no longer
needed for this recovery


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/export/home/oracle/oradata/orcl/redo03.log
Log applied.
Media recovery complete.
  • データベースをオープンする(resetlogs)。
SQL> alter database open resetlogs;

Database altered.
  • 障害発生前の最後の更新が反映されていることを確認する。
SQL> conn scott/tiger
SQL> select name from emp;
NAME
--------------------
neo
smith


[テストシナリオ2(論理バックアップ使用)]

  • 制御ファイルの論理バックアップを取得する。
$ sqlplus / as sysdba
SQL> alter database backup controlfile to trace as '/export/home/oracle/oradata/orcl/control.trc';
  • ログスイッチする。
SQL> alter system archive log current;
SQL> select * from v$log;
    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIV STATUS                           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- ------ -------------------------------- ------------- ------------
         1          1         61   52428800          1 YES    INACTIVE                               1227709 10-JUN-09
         2          1         62   52428800          1 YES    ACTIVE                                 1259238 27-JUN-09
         3          1         63   52428800          1 NO     CURRENT                                1280213 20-JUL-09
SQL> archive log list
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /export/home/oracle/arch01/orcl
Oldest online log sequence     61
Next log sequence to archive   63
Current log sequence           63
  • データを更新してcommitする。
SQL> conn scott/tiger
SQL> select name from emp;

NAME
--------------------
neo

SQL> insert into emp(id, name) values ('01', 'smith');
SQL> commit;
SQL> select name from emp;

NAME
--------------------
neo
smith

SQL> exit
  • 全ての制御ファイルを削除する。
$ rm $ORACLE_BASE/oradata/orcl/*.ctl
$ sqlplus / as sysdba
SQL> shutdown abort
ORACLE instance shut down.
SQL> exit
  • 制御ファイルを再作成する。
$ cd $ORACLE_BASE/oradata/orcl
$ cp control.trc create_controlfile.sql
$ vi create_controlfile.sql
STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 '/export/home/oracle/oradata/orcl/redo01.log'  SIZE 50M,
  GROUP 2 '/export/home/oracle/oradata/orcl/redo02.log'  SIZE 50M,
  GROUP 3 '/export/home/oracle/oradata/orcl/redo03.log'  SIZE 50M
DATAFILE
  '/export/home/oracle/oradata/orcl/system01.dbf',
  '/export/home/oracle/oradata/orcl/undotbs01.dbf',
  '/export/home/oracle/oradata/orcl/sysaux01.dbf',
  '/export/home/oracle/oradata/orcl/users01.dbf'
CHARACTER SET JA16SJIS
;
$ sqlplus / as sysdba
SQL> @create_controlfile.sql
  • データベースをオープンする(noresetlogs)。
SQL> recover database
SQL> alter database open;
  • 一時表領域を作成する。
SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/export/home/oracle/oradata/orcl/temp01.dbf'
 SIZE 210763776  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
  • 障害発生前の最後の更新が反映されていることを確認する。
SQL> conn scott/tiger
SQL> select name from emp;
NAME
--------------------
neo
smith


[参考]
Oracle データベースの復旧手順
ユーザー管理のデータベースのフラッシュバックおよびリカバリの実行

*1:backup controlfile

*2:backup controlfile to trace

*3:10g以降で LOG_ARCHIVE_FORMAT にリセットログID(%r)を含めているものとする。

*4:変更内容はオンラインREDOログのみに存在する

*5:変更内容はオンラインREDOログのみに存在する