トップ > DBA入門 > 14章
15章 RMANを使用したリカバリ
では本章ではRMANツールを使用したリカバリ方法について学んでいきます。

データベース障害によるダウンタイム時間による影響


データベース管理者はデータベースに障害が発生した場合、できるだけ早くデータ
ベースを正常な状態に復旧させる必要があります。もしデータベースの停止時間が
伸びてしまうと、サービスに甚大な影響が出てしまうからです。

例えば証券などのシステムが1時間もデータベースが停止してしまった場合、損害は
数億円の規模になる可能性があります。また最新のデータまで復旧できない場合、
さらに損害は拡大してしまいます。

その為、データベースの復旧は通常は障害発生直前までのデータまで復旧でき、
かつ早急にデータベースを復旧させる必要があります。

データファイル障害


それでは実際にメディア障害を発生させて、データベースを復旧する流れを確認して
いきましょう。ではテーブルを作成し、データファイルを削除しデータベース障害を
発生させてみます。目標は作成したテーブルまで復旧、つまり障害発生直前まで復旧してみます。

 SQL> create table test_tbl (id number(5),name varchar2(10) ) 
   2> tablespace users;

 Table created.

 SQL> insert into test_tbl values (10,'TEST1');

 1 row created.

 SQL> insert into test_tbl values (20,'TEST2');

 1 row created.

 SQL> commit;

 Commit complete.

 SQL> select * from test_tbl;

         ID NAME
 ---------- ----------
         10 TEST1
         20 TEST2


TEST_TBLテーブルをUSERS表領域に作成しました。
実際はSYSユーザで通常のテーブルを作成するのはおすすめしません。。
それではこのUSERS表領域のデータファイルを削除してみます。

  SQL> col file_name for a45
  SQL> col tablespace_name for a20
  SQL> select tablespace_name,file_name from dba_data_files;
  
  TABLESPACE_NAME      FILE_NAME
  -------------------- ---------------------------------------------
  USERS                /u01/app/oracle/oradata/orcl/users01.dbf
  UNDOTBS1             /u01/app/oracle/oradata/orcl/undotbs01.dbf
  SYSTEM               /u01/app/oracle/oradata/orcl/system01.dbf
  SYSAUX               /u01/app/oracle/oradata/orcl/sysaux01.dbf
  TEST3                /u01/app/oracle/oradata/orcl/test3.dbf

  SQL> exit
  
  $ cd /u01/app/oracle/oradata/orcl/
  $ ls -l
  
  合計 2295300
  -rw-r----- 1 oracle oinstall  17973248  9月  5 11:38 2016 control01.ctl
  -rw-r----- 1 oracle oinstall  17973248  9月  5 11:38 2016 control02.ctl
  drwxr-xr-x 2 oracle oinstall      4096  6月 30 18:45 2016 pdb1
  drwxr-x--- 2 oracle oinstall      4096  6月 30 17:56 2016 pdbseed
  -rw-r----- 1 oracle oinstall  52429312  9月  5 06:13 2016 redo01.log
  -rw-r----- 1 oracle oinstall  52429312  9月  5 11:36 2016 redo02.log
  -rw-r----- 1 oracle oinstall  52429312  9月  4 22:35 2016 redo03.log
  -rw-r----- 1 oracle oinstall 912269312  9月  5 11:35 2016 sysaux01.dbf
  -rw-r----- 1 oracle oinstall 838868992  9月  5 11:35 2016 system01.dbf
  -rw-r----- 1 oracle oinstall 206577664  9月  5 11:01 2016 temp01.dbf
  -rw-r----- 1 oracle oinstall  10493952  9月  1 16:50 2016 test01.dbf
  -rw-r----- 1 oracle oinstall  10493952  9月  1 16:50 2016 test02.dbf
  -rw-r----- 1 oracle oinstall  10493952  9月  1 16:50 2016 test03.dbf
  -rw-r----- 1 oracle oinstall  10493952  9月  5 06:19 2016 test3.dbf
  -rw-r----- 1 oracle oinstall 183508992  9月  5 11:35 2016 undotbs01.dbf
  -rw-r----- 1 oracle oinstall   5251072  9月  5 06:19 2016 users01.dbf

  $ rm users01.dbf


この状態でデータファイルの1つが破損した状態です。再度SELECT文を実行してみましょう。

  $ sqlplus / as sysdba

  SQL> select * from test_tbl;

          ID NAME
  ---------- ----------
          10 TEST1
          20 TEST2
         

エラーなくSELECTができました。データファイルを削除したのに、SELECTが
実行できたのはなぜでしょうか。これはデータベースバッファキャッシュ上に
データが残っており、データファイルアクセスがないためです。
それでは一度データベースバッファキャッシュ上のデータをクリアしてみましょう。

  SQL> alter system flush buffer_cache;

  System altered.

  SQL> select * from test_tbl;
  
  select * from test_tbl
  *
  ERROR at line 1:
  ORA-01116: error in opening database file 6
  ORA-01110: data file 6: '/u01/app/oracle/oradata/orcl/users01.dbf'
  ORA-27041: unable to open file
  Linux-x86_64 Error: 2: No such file or directory
  Additional information: 3


ALTER SYSTEM FLUSH文でキャッシュクリアを実施し、
その後、SELECTをするとエラーとなりましたね。
それではこの状態からデータベースを再起動してみましょう。

  SQL> shutdown abort
  ORACLE instance shut down.

  SQL> startup
  ORACLE instance started.

  Total System Global Area  801701888 bytes
  Fixed Size                  2293496 bytes
  Variable Size             327155976 bytes
  Database Buffers          465567744 bytes
  Redo Buffers                6684672 bytes
  Database mounted.
  ORA-01157: cannot identify/lock data file 6 - see DBWR trace file
  ORA-01110: data file 6: '/u01/app/oracle/oradata/orcl/users01.dbf'
  

users01.dbfファイルが存在しない為、起動に失敗しました。
データファイルはMOUNT状態で読み込みを行う為、デーファイルの読み込みに失敗し、MOUNTの状態で停止しています。

次にデータベース管理者は出来るだけデータベースを起動する必要があります。
今回破損しているファイルはUSERS表領域です。USERS表領域は非クリティカル
表領域である為、表領域をOFFLINEにし、DB起動を優先します。

  SQL> select status from v$instance;

  STATUS
  ------------
  MOUNTED

  SQL> alter tablespace usres offline;

  Tablespace altered.

  SQL> alter database open;
 

では、DB起動が完了したので、次からリカバリを実施していきます。

完全リカバリの実施


それでは削除してしまったデータファイルを復旧していきましょう。
バックアップで取得したファイルをリストアします。

リストアの構文は以下の通りです。

リストア構文
 RMAN> restore database;
 RMAN> restore datafile データファイル名(ファイル番号);
 RMAN> restore tablespace 表領域名;

RMANバックアップをリストアする方法はrestoreコマンドを使用します。
restore databaseはすべてのデータファイルをリストアします。
datafile、tablespaceは特定のデータファイルをリストアします。

今回はUSERS表領域のデータファイルのみ破損しているので、USERS表領域の
データファイルのみリストアします。

  $ rman target /

  Recovery Manager: Release 12.1.0.2.0 - Production on XXX XX XX XX:XX:XX 2016

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

  connected to target database: ORCL (DBID=1443685173)

  RMAN> restore tablespace users;

  Starting restore at 05-SEP-16
  using target database control file instead of recovery catalog
  allocated channel: ORA_DISK_1
  channel ORA_DISK_1: SID=58 device type=DISK

  channel ORA_DISK_1: starting datafile backup set restore
  channel ORA_DISK_1: specifying datafile(s) to restore from backup set
  channel ORA_DISK_1: restoring datafile 00006 to /u01/app/oracle/orada
  ta/orcl/users01.dbf
  channel ORA_DISK_1: reading from backup piece /u01/app/oracle/product
  /12.0.1/dbhome_1/dbs/01rf0obn_1_1
  channel ORA_DISK_1: piece handle=/u01/app/oracle/product/12.0.1/dbhom
  e_1/dbs/01rf0obn_1_1 tag=TAG20160905T021415
  channel ORA_DISK_1: restored backup piece 1
  channel ORA_DISK_1: restore complete, elapsed time: 00:00:08
  Finished restore at 05-SEP-16

  RMAN>
  

これだけでリストアは完了です。RMANを使用すると簡単にリストアできますね。
現在USERS表領域のデータファイルのみ過去のバックアップファイルからリストア
したので、USERS表領域のみ過去の状態となっています。

この状態でUSERS表領域をONLINEにしてもエラーになります。

  RMAN> alter tablespace users online;

  RMAN-00571: ===========================================================
  RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
  RMAN-00571: ===========================================================
  RMAN-03002: failure of sql statement command at XX/XX/2016 XX:XX:XX
  ORA-01113: file 6 needs media recovery
  ORA-01110: data file 6: '/u01/app/oracle/oradata/orcl/users01.dbf'

  RMAN>
  

理由はその他の表領域は最新の状態ですが、USERS表領域はリストアしたため、
過去の状態となっています。
OracleはデータファイルのSCNがすべて最新であるかをチェックしているため、
古いSCNのデータファイルの表領域はONLINEにできません。

それではリストアしたデータファイルのSCNを最新にするため、アーカイブログと
REDOログファイルを適用していきます。

リカバリ構文
 RMAN> recover database;
 RMAN> recover datafile データファイル名(ファイル番号);
 RMAN> recover tablespace 表領域名;

リカバリ構文はRESTORE構文と同様です。適用するアーカイブログファイルは
RECOVERコマンドを実行すると自動的に必要なアーカイブログを適用してくれます。

  RMAN> recover tablespace users;

  Starting recover at 06-SEP-16
  using target database control file instead of recovery catalog
  allocated channel: ORA_DISK_1
  channel ORA_DISK_1: SID=7 device type=DISK

  starting media recovery

  archived log for thread 1 with sequence 40 is already on disk as file
   /home/oracle/arch/1_40_915904440.dbf
  archived log for thread 1 with sequence 41 is already on disk as file
   /home/oracle/arch/1_41_915904440.dbf
  archived log for thread 1 with sequence 42 is already on disk as file
   /home/oracle/arch/1_42_915904440.dbf
  archived log for thread 1 with sequence 43 is already on disk as file
   /home/oracle/arch/1_43_915904440.dbf
  archived log file name=/home/oracle/arch/1_40_915904440.dbf
   thread=1 sequence=40
  archived log file name=/home/oracle/arch/1_41_915904440.dbf
   thread=1 sequence=41
  media recovery complete, elapsed time: 00:00:19
  Finished recover at 06-SEP-16

  RMAN>
  

上記でリカバリが完了し、データファイル障害直前までの更新が復旧されました。
それでは表領域をONLINEにし、バックアップ取得以降に更新されたレコードが
存在するか確認してみます。

  $ sqlplus / as sysdba
  SQL> alter tablespace users online;

  Tablespace altered.

  SQL> select * from test_tbl;

          ID NAME
  ---------- ----------
          10 TEST1
          20 TEST2
         

TEST_TBLテーブルはバックアップ以降に作成し2レコードを挿入しましたが、
ちゃんと障害発生直前に戻っていますね。
このように障害発生直前までのリカバリを完全リカバリと言います。

不完全リカバリの実施


基本的にデータは障害発生直前に戻す必要がありますが、
データベースを過去の状態に戻したい場合などは不完全リカバリを実施します。
例えば、誤ってテーブルを削除してしまった場合、復旧するためには削除する前、
つまり過去の状態にする必要があります。

不完全リカバリ構文
 RMAN> recover database until [ SCN | SEQUENCE | TIME | RESTORE POINT];

不完全リカバリはすべてのデータファイルをリストアする必要があります。
これは前回ご説明したように、OracleではすべてのデータファイルのSCNを同じに
する必要があります。その為、1つの表領域だけ過去にすることはできません。

SCN リカバリを実施するSCNを指定します。
SEQUENCE 適用するログ順序番号を指定します。
TIME 戻す時間を指定します。
RESTORE POINT 作成したリストアポイントを指定します。

では実際に試してみましょう。今回は誤ってテーブルを削除してしまった時を想定し、 リカバリを実施してみます。

  $ sqlplus / as sysdba
  
  SQL> create restore point before_drop;
  
  restore point created.

  SQL> drop table test_tbl;
  
  table droped.

  Tablespace altered.

  SQL> select * from test_tbl;

          ID NAME
  ---------- ----------
          10 TEST1
          20 TEST2
         

今回はリストアポイントを作成し、リストアポイント時点に復旧したいと思います。
では不完全リカバリ時のリストアはデータベース全体です。

  $ rman target /
  RMAN> restore database;

  Starting restore at 06-SEP-16
  using target database control file instead of recovery catalog
  allocated channel: ORA_DISK_1
  channel ORA_DISK_1: SID=7 device type=DISK

  skipping datafile 1; already restored to file /u01/app/oracle/oradata/orcl/
  system01.dbf
  skipping datafile 3; already restored to file /u01/app/oracle/oradata/orcl/
  sysaux01.dbf
  skipping datafile 4; already restored to file /u01/app/oracle/oradata/orcl/
  undotbs01.dbf
  skipping datafile 6; already restored to file /u01/app/oracle/oradata/orcl/
  users01.dbf
  skipping datafile 15; already restored to file /u01/app/oracle/oradata/orcl/
  test3.dbf
  channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
  Finished restore at 07-SEP-15


  RMAN> list restore point all;

  SCN              RSP Time  Type       Time      Name
  ---------------- --------- ---------- --------- ----
  2809663                               06-SEP-16 BEFORE_DROP

  RMAN> recover database until restore point before_drop;

  Starting recover at 06-SEP-16
  using channel ORA_DISK_1

  starting media recovery

  archived log for thread 1 with sequence 40 is already on disk as file
   /home/oracle/arch/1_40_915904440.dbf
  archived log for thread 1 with sequence 41 is already on disk as file
   /home/oracle/arch/1_41_915904440.dbf
  archived log for thread 1 with sequence 42 is already on disk as file
   /home/oracle/arch/1_42_915904440.dbf
  archived log for thread 1 with sequence 43 is already on disk as file
   /home/oracle/arch/1_43_915904440.dbf
  archived log for thread 1 with sequence 44 is already on disk as file
   /home/oracle/arch/1_44_915904440.dbf
  archived log file name=/home/oracle/arch/1_40_915904440.dbf
   thread=1 sequence=40
  archived log file name=/home/oracle/arch/1_41_915904440.dbf
   thread=1 sequence=41
  archived log file name=/home/oracle/arch/1_42_915904440.dbf
   thread=1 sequence=42
  media recovery complete, elapsed time: 00:04:37
  Finished recover at 06-SEP-16

  RMAN> alter database open resetlogs;

  Statement processed


不完全リカバリの場合、データベース起動時にresetlogsオプションが必要です。
resetlogsを実行するとREDOログの情報がクリアされ、ログ順序番号は1に戻ります。
では最後に削除してしまった表が戻っているか確認してみます。

  $ sqlplus / as sysdba
  
  SQL> select * from test_tbl;

          ID NAME
  ---------- ----------
          10 TEST1
          20 TEST2
         

TEST_TBLテーブルは戻っていることが確認できました。
こちらが不完全リカバリの実行方法です。
完全リカバリの手順と異なる点はすべてのREDOログを適用しない為、
RECOVERコマンド時にUNTIL句を使用してどこの時点までログを適用するかの
指定が必要です。

それでは本章は以上となります。DBリカバリの方法がイメージできたでしょうか。
一度自分の環境で試してみることをお勧めします。