3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FLASHBACK DATA ARCHIVEを試す

Last updated at Posted at 2018-05-10

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
3
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?