こんにちは。エンジニアの相島です。
突然ですが皆さんは過去に戻りたいと思ったことはありませんか。
仕事に限らず、普段の生活でも「食べ過ぎてしまった」「無駄なものを買ってしまった」
「株で少し損をしてしまった」などなど。
大した事ではないけれど、もし戻れるなら戻りたいと思ったことがあるはずです。
上記に挙げた例は残念ながらどれも実施することができませんが、
Oracleにはフラッシュバック機能というものがあり、ある一定期間内であれば
過去のデータを参照したり過去のデータに戻したりすることが簡単にできます。
※過去にデータを戻す場合は、その過程でデータベースの再起動が必要となります。
データベースの再起動はデータベース全体に影響を与えるため、
その影響度を十分に考慮した上で実施する必要があります。
今回はフラッシュバック機能の中でも「フラッシュバックデータベース」についてご紹介します。
フラッシュバックデータベースとは?
フラッシュバックデータベースは、論理的なデータ破損、もしくはユーザーエラーによって発生した問題を修正するためにOracleデータベースを過去のある時点に戻す機能です。
図. フラッシュバックデータベースのイメージ
商用データベースはデータファイルに障害が起きてシステムが停止した際、一般的に事前に取得しておいたバックアップファイルからリストア・リカバリします。Oracle でもRecovery Manager(RMAN)というバックアップ、リストア、リカバリ操作ができる機能が標準で提供されています。フラッシュバックデータベースは、このようなバックアップ、リストアの操作を行わず、過去の特定の時間のデータに戻すことができる機能です。そのため状況によってはRMANでバックアップデータからリストアするよりも高速でデータを復旧することができます。
冒頭で「大した事ではないけれど」と言いましたが、データファイル破損や制御ファイル破損は大きい問題なため、リストア・リカバリ操作にて復旧をしなければなりません。しかし、論理的なデータ破損レベルであれば、そういった操作を必要とせずに、フラッシュバックデータベース機能を使用してフラッシュバックバック・ログとREDOログから短時間で過去のデータに巻き戻せます。
表. フラッシュバックデータベースのリカバリ可能範囲
リカバリ可能 |
リカバリ不可能 |
▼DML処理による変更 DROP USER |
▼メディア障害 表領域の削除・データファイルの縮小など ▼NOLOGGING操作を実施した地点へのフラッシュバック NOLOGGING操作を実行した場合、変更情報がREDOログに記録されない。考慮なしフラッシュバックデータベースを実行すると、NOLOGGING操作済みのオブジェクト等でブロック破損が発生する可能性がある。 |
フラッシュバックデータベースを選択する場面は限られてきますが、意図と違う処理をうっかり実行してデータを論理的に破壊してしまった等、バックアップから戻す時間がないという時に助けてくれる便利な機能です。
フラッシュバックデータベースを実行してみよう!
では、実際にフラッシュバックデータベースを実行してみましょう。
ここからはフラッシュバックデータベースを使用する為に必要な設定と、実機を使ったフラッシュバックデータベース操作の説明をします。※具体的な設定方法は割愛いたします。
◆検証環境
OS: Red Hat Enterprise Linux Server release 6.4
Oracle Version: Oracle Database 11g Enterprise Edition Release 11.2.0.4
1. 事前設定
フラッシュバックデータベースを使用するには、以下の設定が必要です。
<ARCHIVELOGモード有効化設定>
ARCHIVELOGモードにします。
SQL> select LOG_MODE from v$DATABASE;
LOG_MODE
-------------------------
ARCHIVELOG
<高速リカバリ領域初期化パラメータ設定>
・db_recovery_file_dest_size
高速リカバリ領域のサイズを指定します。
※実務上の運用方針によって設定値は異なる。
SQL> show parameters db_recovery_file_dest_size
NAME TYPE VALUE
---------------------------------------------- -------------------- ----------------
db_recovery_file_dest_size big integer 2G
・db_recovery_file_dest
フラッシュバック・ログの格納場所を指定します。
※実務上の運用方針によって設定値は異なる。
SQL> show parameters db_recovery_file_dest
NAME TYPE VALUE
-------------------------------------------- ------------------- ------------------
db_recovery_file_dest string +DATA
※フラッシュバック・ログとは更新前の論理的な変更情報を格納したログです。
変更の度に自動で生成され、db_flashback_retention_target初期化パラメータ
で設定した期間のログは保持されます。
しかし、ログの保持期間の範囲であっても、フラッシュバック・ログが保存されている高速リカバリ領域が一杯になった場合は、古いフラッシュバック・ログが削除されます。
・db_flashback_retention_target
フラッシュバックデータベース使用期間を設定できます。
※デフォルトは1440(1日)。実務上の運用方針によって設定値は異なる。
SQL> show parameters db_flashback_retention_target
NAME TYPE VALUE
----------------------------------------- --------------------- -------------------
db_flashback_retention_target integer 1440
<フラッシュバックデータベースの有効化>
SQL> select FLASHBACK_ON from v$DATABASE;
FLASHBACK_ON
------------------
YES
(例)フラッシュバック・ログ
SQL> select NAME, BYTES from V$FLASHBACK_DATABASE_LOGFILE;
NAME BYTES
--------------------------------------------------------- -----------------------------
+DATA/orcl/flashback/log_1.282.851991307 52428800
+DATA/orcl/flashback/log_2.283.851991315 52428800
+DATA/orcl/flashback/log_4.306.852323793 52428800
+DATA/orcl/flashback/log_3.300.852318185 52428800
2. フラッシュバックデータベース
以下のテストデータを使用して実際に過去の日時に巻き戻せるか検証します。
テストでは表データ更新でミスオペレーションがあった場合を想定します。
TESTTBS という表領域の中に test_table という名前の表があり、
以下のデータが入っています。
SQL> select * from test_table;
NUM COL1
--------------- ---------------
1 data1
2
3
a. 表のCOL1をUPDATE(正)
SQL> update test_table set COL1='data2' where NUM=2;
1 row updated.
SQL> commit;
Commit complete.
SQL> select sysdate from dual;
SYSDATE
-------------------
2014-07-04 20:24:47
SQL> select * from test_table;
NUM COL1
--------------- ---------------
1 data1
2 data2
3
b. 表のCOL1をUPDATE(誤)
SQL> update test_table set COL1='data3';
3 rows updated. <= 誤って3列全てUPDATEをかけた。
SQL> commit;
Commit complete.
SQL> select sysdate from dual;
SYSDATE
-------------------
2014-07-04 20:28:02
SQL> select * from test_table;
NUM COL1
--------------- ---------------
1 data3 <= 本来はdata1
2 data3 <= 本来はdata2
3 data3
COL1のNUM3にdata3を入れようとしたところ、誤ってCOL1全てをUPDATEしてしまいました。
このオペレーションをフラッシュバックデータベースで過去に巻き戻して取り消します。
c. フラッシュバック可能な最大日時を特定
フラッシュバック・ログが残っている最大日時を特定し、
ミスオペレーションした日時よりも古いことを確認します。
※フラッシュバック可能な最大日時より古いデータへ戻すことはできません。
SQL> select OLDEST_FLASHBACK_SCN oldest_scn,
2 to_char(OLDEST_FLASHBACK_TIME,'YYYYMMDD HH24:MI:SS') oldest_time
3 from V$FLASHBACK_DATABASE_LOG;
OLDEST_SCN OLDEST_TIME
----------------------- -----------------------------
853532 20140704 00:15:14
d. フラッシュバックデータベースの実施
手順bのオペレーションミスの時間よりも前の時間を指定します。
今回は手順aの終了後の時点に巻き戻します。
※データベースの再起動を実施するため、その影響度を十分考慮してください。
※実行ユーザはデータベース管理者ユーザであるSYSです。
・データベースを停止しマウント状態で起動
以降フラッシュバックデータベースの一連の操作が完了するまでデータベースは使用できません。
[oracle]$ sqlplus / as sysdba
SQL> shutdown immediate;
SQL> startup mount
SQL> exit
・フラッシュバックデータベース操作
[oracle]$ rman target /
RMAN> sql 'alter session set nls_date_format=YYYYMMDDHH24MISS';
RMAN> flashback database to time '20140704202500'; <=手順aを実行したときの大まかな時間を指定。
Starting flashback at 04-JUL-14
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=26 device type=DISK
starting media recovery
media recovery complete, elapsed time: 00:00:07
Finished flashback at 04-JUL-14
e. 手順aのデータに戻っていることを確認
意図したデータに戻っているか確認するため、read onlyオプションでデータベースをオープンし、
問題なければ戻した時点以降のログは不要なためログリセットを実施しデータベースをOPENします。
[oracle]$ sqlplus / as sysdba
SQL> alter database open read only;
Database altered.
SQL> select * from test_table;
NUM COL1
----------------- ----------------
1 data1 <=戻っている
2 data2 <=戻っている
3 <=戻っている
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database open resetlogs;
Database altered.
これでフラッシュバックデータベースの操作は完了です。
気をつけるポイントは、フラッシュバックデータベースはデータベース全体の巻き戻しを行うという点です。
実務で使用する場合、すべて論理上の変更が戻ってしまうため、間違った操作だけでなく、正しい操作も実行前の状態に戻ってしまいます。そのため、フラッシュバックデータベース機能にて指定した時間以降に行われたデータベース操作は、改めて手動でデータベースに反映する必要があります。
最後に
最後に余談となりますが、フラッシュバックデータベースではリカバリできないという、
特定の操作をしたらどうなるのかをみてみましょう。
ここでは、表領域の削除で検証します。
まず、先程のtest_table表をTESTTBS表領域ごとデータファイルとともに削除します。
SQL> drop tablespace TESTTBS including contents and datafiles;
Tablespace dropped.
その後、フラッシュバックデータベースを実行し、test_table表に問い合わせてみます。
さて、どうなるでしょうか...?
SQL> select * from test_table;
select * from test_table
*
ERROR at line 1:
ORA-00376: file 5 cannot be read at this time
ORA-01110: data file 5:
'/opt/oracle/app/product/11.2.0/dbhome_1/dbs/UNNAMED00005'
結果は、データファイルが削除されたままになっているためエラーになります。
このような場合は素直にバックアップファイルからリストア・リカバリをしましょう。
以上です。