FLASHBACK DATA ARCHIVEとは?
Oracle Databaseは基本的に最新のデータを保存し、利用者に提供します。UPDATE文やDELETE文による更新前のデータは参照整合性維持のために一時的にUNDO表領域に格納されますが、一定時間経過すると自動的に削除されます。
FLASHBACK DATA ARCHIVE機能は、UNDO表領域に保存される過去データを別領域に自動的に永続化するOracle Database Enterprise Editionの標準機能です。更新前データがUNDO表領域から削除された後でもSELECT * FROM AS OF文を使って過去データを参照することができます。
過去データを保存するオブジェクトをFLASHBACK ARCHIVEと呼びます。FLASHBACK ARCHIVEオブジェクトは通常のテーブルとは異なる領域/フォーマットで管理されているため、改ざんされていないことを保証してデータベースの過去の状態を取得することができます。アプリケーションに変更を加えずに過去データを簡単に参照することができ、改ざんの検知や過去の状態の検証に有効です。履歴を保存するかの決定はテーブル単位に指定できます。
FLASHBACK ARCHIVEの管理
SYSユーザーでもかまいませんが、FLASHBACK ARCHIVEの管理を行うユーザーにはFLASHBACK ARCHIVE ADMINISTERロールを付与する必要があります。
下記の例ではfdadminユーザーにFLASHBACK ARCHIVE ADMIINSTERロールを付与しています。
SQL> GRANT FLASHBACK ARCHIVE ADMINISTER TO fdadmin;
権限付与が成功しました。
権限を付与したユーザーはFLASHBACK ARCHIVEオブジェクトを作成することができます。オブジェクト名、データの保存期間、最大容量を指定します。
作成にはCREATE FLASHBACK ARCHIVE文を使います。下記の例では最大容量10MB、保存期間を1年としています。
作成したFLASHBACK ARCHIVEの情報はDBA_FLASHBACK_ARCHIVEビューとDBA_FLASHBACK_ARCHIVE_TSビューから参照できます。しかしDBA_OBJECTSビューには情報が登録されません。
SQL> CREATE FLASHBACK ARCHIVE fla1 TABLESPACE ts1 QUOTA 10M RETENTION 1 YEAR;
フラッシュバック・アーカイブが作成されました。
SQL> SELECT FLASHBACK_ARCHIVE_NAME, RETENTION_IN_DAYS FROM DBA_FLASHBACK_ARCHIVE;
FLASHBACK_ARCHIVE_NAME RETENTION_IN_DAYS
------------------------------ -----------------
FLA1 365
SQL> SELECT FLASHBACK_ARCHIVE_NAME, TABLESPACE_NAME, QUOTA_IN_MB FROM DBA_FLASHBACK_ARCHIVE_TS;
FLASHBACK_ARCHIVE_NAME TABLESPACE_NAME QUOTA_IN_MB
------------------------------ ------------------------------ ----------------------------------------
FLA1 TS1 10
SQL> SELECT COUNT(*) FROM dba_objects WHERE owner='FDADMIN';
レコードが選択されませんでした。
作成したFLASHBACK ARCHIVEをユーザーが利用できるようにFLASHBACK ARCHIVE権オブジェクト限を付与します。下記の例ではfduserユーザーに対して作成したFLASHBACK ARCHIVE fla1の利用を許可しています。
SQL> GRANT FLASHBACK ARCHIVE ON fla1 TO fduser;
権限付与が成功しました。
FLASHBACK ARCHIVEに登録されたテーブルの情報はDBA_FLASHBACK_ARCHIVE_TABLESビューから参照できます。
SQL> SELECT TABLE_NAME, FLASHBACK_ARCHIVE_NAME FROM dba_flashback_archive_tables;
TABLE_NAME FLASHBACK_ARCHIVE_NAME
------------------------------ ------------------------------
DATA1 FLA1
FLASHBACK ARCHIVEの設定変更や、履歴データの削除にはALTER FLASHBACK ARCHIVE文を実行します。
ALTER FLASHBACK ARCHIVE文は下記の用途で使用できます。
- デフォルトのFLASHBACK ARCHIVE設定 (ALTER FLASHBACK ARCHIVE SET DEFAULT)
- 領域の追加 (ALTER FLASHBACK ARCHIVE ADD TABLESPACE | MODIFY TABLESPACE)
- 領域の削除 (ALTER FLASHBACK ARCHIVE REMOVE TABLESPACE)
- 履歴データの削除(ALTER FLASHBACK ARCHIVE PURGE BEFORE TIMESTAPM | PURGE ALL)
- 最適化設定(ALTER FLASHBACK ARCHIVE OPTIMIZE DATA)
FLASHBACK ARCHIVEの利用
FLASHBACK ARCHIVEを利用するユーザーは、CREATE TABLE文またはALTER TABLE文でFLASHBACK ARCHIVE句を指定します。下記の例ではdata1テーブルを作成し、FLASHBACK ARCHIVEとしてfla1を指定しています。FLASHBACK ARCHIVEオブジェクト権限が指定されていない場合、「ORA-55620: フラッシュバック・アーカイブの使用権限がありません」エラーが発生します。
SQL> CREATE TABLE data1(c1 NUMBER PRIMARY KEY, c2 VARCHAR2(10)) FLASHBACK ARCHIVE fla1;
表が作成されました。
過去データを参照するにはAS OF句を使ってテーブルを検索するだけです。
下記の例では、c1=1000のレコードを更新していますが、10分前のレコードを参照しています。
SQL> UPDATE data1 SET c2='update' WHERE c1=1000;
1行が更新されました。
SQL> SELECT * FROM data1 WHERE c1=1000;
C1 C2
---------- ----------
1000 update
SQL> SELECT * FROM fduser.data1 AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '10' MINUTE) WHERE c1=1000;
C1 C2
---------- ----------
1000 data1
FLASHBACK ARCHIVE を参照する場合には実行計画に表示が現れます。
SQL> SELECT * FROM fduser.data1 AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '5' MINUTE);
レコードが選択されませんでした。
実行計画
----------------------------------------------------------
Plan hash value: 75922806
-----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | |2 | 70 | 5 (0)| 00:00:01 | | |
| 1 | VIEW | |2 | 70 | 5 (0)| 00:00:01 | | |
| 2 | UNION-ALL | | | | | | | |
|* 3 | FILTER | | | | | | | |
| 4 | PARTITION RANGE SINGLE | |1 | 63 | 2 (0)| 00:00:01 | KEY | 1 |
|* 5 | TABLE ACCESS FULL | SYS_FBA_HIST_26363 |1 | 63 | 2 (0)| 00:00:01 | KEY | 1 |
|* 6 | FILTER | | | | | | | |
| 7 | NESTED LOOPS OUTER | |1 | 2075 | 3 (0)| 00:00:01 | | |
|* 8 | TABLE ACCESS FULL | DATA1 |1 | 47 | 2 (0)| 00:00:01 | | |
|* 9 | TABLE ACCESS BY INDEX ROWID BATCHED| SYS_FBA_TCRV_26363 |1 | 2028 | 1 (0)| 00:00:01 | | |
|* 10 | INDEX RANGE SCAN | SYS_FBA_TCRV_IDX1_26363 |1 | | 1 (0)| 00:00:01 | | |
-----------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("TIMESTAMP_TO_SCN"(SYSTIMESTAMP(6)-INTERVAL'+00 00:05:00' DAY(2) TO SECOND(0))<1203424)
5 - filter("ENDSCN"<=1203424 AND ("OPERATION" IS NULL OR "OPERATION"<>'D') AND
"ENDSCN">"TIMESTAMP_TO_SCN"(SYSTIMESTAMP(6)-INTERVAL'+00 00:05:00' DAY(2) TO SECOND(0)) AND ("STARTSCN" IS NULL OR
"STARTSCN"<="TIMESTAMP_TO_SCN"(SYSTIMESTAMP(6)-INTERVAL'+00 00:05:00' DAY(2) TO SECOND(0))))
6 - filter("STARTSCN"<="TIMESTAMP_TO_SCN"(SYSTIMESTAMP(6)-INTERVAL'+00 00:05:00' DAY(2) TO SECOND(0)) OR "STARTSCN" IS NULL)
8 - filter(("T"."VERSIONS_OPERATION" IS NULL OR "T"."VERSIONS_OPERATION"<>'D') AND ("T"."VERSIONS_STARTSCN" IS NULL OR
"T"."VERSIONS_STARTSCN"<="TIMESTAMP_TO_SCN"(SYSTIMESTAMP(6)-INTERVAL'+00 00:05:00' DAY(2) TO SECOND(0))) AND
("T"."VERSIONS_ENDSCN" IS NULL OR "T"."VERSIONS_ENDSCN">"TIMESTAMP_TO_SCN"(SYSTIMESTAMP(6)-INTERVAL'+00 00:05:00' DAY(2)
TO SECOND(0))))
9 - filter(("ENDSCN"(+) IS NULL OR "ENDSCN"(+)>1203424) AND ("STARTSCN"(+) IS NULL OR "STARTSCN"(+)<1203424))
10 - access("RID"(+)=ROWIDTOCHAR("T".ROWID))
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
統計
----------------------------------------------------------
341 recursive calls
37 db block gets
322 consistent gets
1 physical reads
7032 redo size
425 bytes sent via SQL*Net to client
596 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
22 sorts (memory)
0 sorts (disk)
0 rows processed