68 DBMS_FLASHBACK

DBMS_FLASHBACKを使用して、指定した時間または指定したシステム変更番号(SCN)にデータベースのバージョンをフラッシュバックできます。

この章のトピックは、次のとおりです:

参照:

DBMS_FLASHBACKの詳細は、次のマニュアルを参照してください。

68.1 DBMS_FLASHBACKの概要

DBMS_FLASHBACKは、ユーザーが過去の特定の時点でのデータベースを表示するためのインタフェースを提供し、個々のトランザクションの結果を選択して削除できるトランザクション・バックアウト機能も追加されています。データベースを過去の時点に戻すフラッシュバック・データベースとは異なります。

DBMS_FLASHBACKが有効化された場合、ユーザー・セッションはデータベースのフラッシュバック・バージョンを使用します。また、アプリケーションをデータベースのフラッシュバック・バージョンで実行することができます。

DBMS_FLASHBACKは、次のような場合に使用できます。

  • 自己修復: 誤って表から行を削除してしまった場合、その行をリカバリできます。

  • 電子メールおよびボイスメールなどのパッケージ・アプリケーション: フラッシュバックを使用して、現行のメッセージ・ボックスに削除したメッセージを再挿入し、削除した電子メールをリストアできます。

  • 意思決定支援システム(DSS)およびオンライン分析処理(OLAP)アプリケーション: データ分析またはデータ・モデリングを実行し、季節的需要の推移を見ることができます。

68.2 DBMS_FLASHBACKのセキュリティ・モデル

DBMS_FLASHBACKパッケージを使用するには、パッケージに対するEXECUTE権限が必要です。

68.3 DBMS_FLASHBACKのタイプ

次の表に、DBMS_FLASHBACKによって使用されるタイプを説明します。

表68-1 DBMS_FLASHBACK

タイプ 説明

TXNAME_ARRAY

トランザクション名またはトランザクション識別子(XID)を保持するためのVARRAYを作成します。

68.4 DBMS_FLASHBACKの例外

DBMS_FLASHBACKでは、次のエラー・メッセージが作成されます。

表68-2 DBMS_FLASHBACKエラー・メッセージ

エラー 説明

ORA-08180

指定された時間が古すぎます。

ORA-08181

無効なシステム変更番号が指定されました。

ORA-08182

ユーザーは、フラッシュバック・モードにおいて、読取り専用またはシリアル化可能トランザクションを開始できません。

ORA-08183

ユーザーは、コミットされていないトランザクションにおいてフラッシュバックを有効化できません。

ORA-08184

ユーザーは、別のフラッシュバック・セッションにおいてフラッシュバックを有効化できません。

ORA-08185

SYSはフラッシュバック・モードを有効化できません。

68.5 DBMS_FLASHBACKの操作上のノート

接続切断または別の接続の開始によりセッションが終了すると、DBMS_FLASHBACKは自動的に無効化されます。

フラッシュバック・モードでオープンされたPL/SQLカーソルは、フラッシュバック時間またはSCNの時点での行を戻します。データベースにおける異なる同時セッション(接続)では、異なる実時間またはSCNに対してフラッシュバックを実行できます。セッションがフラッシュバック・モードで実行されている間は、DMLおよびDDL処理ならびに分散処理を行うことはできません。オープンしているPL/SQLカーソルは、フラッシュバックを無効にしてDMLを実行するまで使用できます。

自動UNDO管理(AUM)モードでは、保存期間コントロールを使用して、必要なデータベース・バージョンを取得するためにどのくらい過去に戻るかを制御できます。過去24時間のフラッシュバックを実行する必要がある場合は、DBAはundo_retentionパラメータを24時間に設定する必要があります。このように、システムはデータの旧バージョンを再生成するのに十分なロールバック情報を保持しています。

UNDO表領域に対しRETENTION GUARANTEE句を設定すると、期限切れになっていないUNDOが廃棄されないようにできます。システムの領域が小さくなると、期限切れになっていないUNDOは新たに生成されたUNDOで上書きされる可能性があるため、 UNDO_RETENTION自体は保証されません。このような状況は、RETENTION GUARANTEEによって防ぐことができます。詳細は、Oracle Database管理者ガイドを参照してください。

フラッシュバックが有効化されたセッションでは、SYSDATEは影響を受けません。引き続き、現在の時間が提供されます。

ログイン・トリガーにおいてDBMS_FLASHBACKを使用し、アプリケーション・コードを変更せずにフラッシュバックを有効化できます。

参照:

最小UNDO保存期間の設定の詳細は、Oracle Database管理者ガイドを参照してください。

68.6 DBMS_FLASHBACKの例

高年齢従業員を削除したことにより、その従業員に提出された人員レポートがすべて削除された場合に、フラッシュバックを使用する方法を次に示します。フラッシュバック機能を使用すると、消失した従業員をリカバリし、再挿入できます。

DROP TABLE employee;
DROP TABLE keep_scn;

REM -- Keep_scn is a temporary table to store scns that we are interested in

CREATE TABLE keep_scn (scn number); 
SET ECHO ON 
CREATE TABLE employee ( 
   employee_no   number(5) PRIMARY KEY, 
   employee_name varchar2(20), 
   employee_mgr  number(5) 
      CONSTRAINT mgr_fkey REFERENCES EMPLOYEE ON DELETE CASCADE, 
   salary        number, 
   hiredate      date 
); 

REM -- Populate the company with employees
INSERT INTO employee VALUES (1, 'John Doe', null, 1000000, '5-jul-81'); 
INSERT INTO employee VALUES (10, 'Joe Johnson', 1, 500000, '12-aug-84'); 
INSERT INTO employee VALUES (20, 'Susie Tiger', 10, 250000, '13-dec-90'); 
INSERT INTO employee VALUES (100, 'Scott Tiger', 20, 200000, '3-feb-86'); 
INSERT INTO employee VALUES (200, 'Charles Smith', 100, 150000, '22-mar-88'); 
INSERT INTO employee VALUES (210, 'Jane Johnson', 100, 100000, '11-apr-87'); 
INSERT INTO employee VALUES (220, 'Nancy Doe', 100, 100000, '18-sep-93'); 
INSERT INTO employee VALUES (300, 'Gary Smith', 210, 75000, '4-nov-96'); 
INSERT INTO employee VALUES (310, 'Bob Smith', 210, 65000, '3-may-95'); 
COMMIT; 

REM -- Show the entire org
SELECT lpad(' ', 2*(level-1)) || employee_name Name 
FROM employee 
CONNECT BY PRIOR employee_no = employee_mgr 
START WITH employee_no = 1 
ORDER BY LEVEL; 

REM -- Sleep for a short time (approximately 10 to 20  seconds) to avoid 
REM -- querying close to table creation

EXECUTE DBMS_LOCK.SLEEP(10);

REM -- Store this snapshot for later access through Flashback
DECLARE 
I NUMBER; 
BEGIN 
I := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER; 
INSERT INTO keep_scn VALUES (I); 
COMMIT; 
END;
/

REM -- Scott decides to retire but the transaction is done incorrectly
DELETE FROM EMPLOYEE WHERE employee_name = 'Scott Tiger'; 
COMMIT; 

REM -- notice that all of scott's employees are gone 
SELECT lpad(' ', 2*(level-1)) || employee_name Name 
FROM EMPLOYEE 
CONNECT BY PRIOR employee_no = employee_mgr 
START WITH employee_no = 1 
ORDER BY LEVEL; 

REM -- Flashback to see Scott's organization
DECLARE 
   restore_scn number; 
BEGIN 
   SELECT  scn INTO restore_scn FROM keep_scn; 
   DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER (restore_scn); 
END; 
/ 

REM -- Show Scott's org.
SELECT lpad(' ', 2*(level-1)) || employee_name Name 
FROM employee 
CONNECT BY PRIOR employee_no = employee_mgr 
START WITH employee_no = 
   (SELECT employee_no FROM employee WHERE employee_name = 'Scott Tiger') 
ORDER BY LEVEL; 

REM -- Restore scott's organization.
DECLARE 
   scotts_emp NUMBER; 
   scotts_mgr NUMBER; 
   CURSOR c1 IS 
      SELECT employee_no, employee_name, employee_mgr, salary, hiredate 
      FROM employee 
      CONNECT BY PRIOR employee_no = employee_mgr 
      START WITH employee_no = 
         (SELECT employee_no FROM employee WHERE employee_name = 'Scott Tiger'); 
   c1_rec c1 % ROWTYPE; 
BEGIN 
   SELECT employee_no, employee_mgr INTO scotts_emp, scotts_mgr FROM employee 
   WHERE employee_name = 'Scott Tiger'; 
   /* Open c1 in flashback mode */
   OPEN c1; 
   /* Disable Flashback */
   DBMS_FLASHBACK.DISABLE; 
 LOOP 
   FETCH c1 INTO c1_rec; 
   EXIT WHEN c1%NOTFOUND; 
   /*
     Note that all the DML operations inside the loop are performed
     with Flashback disabled
   */
   IF (c1_rec.employee_mgr = scotts_emp) then 
      INSERT INTO employee VALUES (c1_rec.employee_no, 
         c1_rec.employee_name, 
         scotts_mgr, 
         c1_rec.salary, 
         c1_rec.hiredate); 
   ELSE 
   IF (c1_rec.employee_no != scotts_emp) THEN 
   INSERT INTO employee VALUES (c1_rec.employee_no, 
         c1_rec.employee_name, 
         c1_rec.employee_mgr, 
         c1_rec.salary, 
         c1_rec.hiredate); 
      END IF; 
    END IF; 
 END LOOP; 
END; 
/ 

REM -- Show the restored organization.
select lpad(' ', 2*(level-1)) || employee_name Name 
FROM employee 
CONNECT BY PRIOR employee_no = employee_mgr 
START WITH employee_no = 1 
ORDER BY LEVEL; 

68.7 DBMS_FLASHBACKサブプログラムの要約

この表は、DBMS_FLASHBACKサブプログラムを示し、簡単に説明しています。

表68-3 DBMS_FLASHBACKパッケージのサブプログラム

サブプログラム 説明

DISABLEプロシージャ

セッション全体においてフラッシュバック・モードを無効化します。

ENABLE_AT_SYSTEM_CHANGE_NUMBERプロシージャ

セッション全体においてフラッシュバックを使用できるようにします。SCNをOracleの数値タイプとして使用し、セッションのスナップショットを指定した数値に設定します。フラッシュバック・モードでは、すべての問合せにおいて、指定した実時間またはSCNの時点と一致したデータが戻されます。

ENABLE_AT_TIMEプロシージャ

セッション全体においてフラッシュバックを使用できるようにします。スナップショット・タイムは、query_timeで指定された時間に最も近いSCNに設定されます。

GET_SYSTEM_CHANGE_NUMBERファンクション

現在のSCNをOracleの数値タイプとして戻します。SCNを使用して、特定のスナップショットを格納できます。

TRANSACTION_BACKOUTプロシージャ

トランザクションをバックアウトするためのメカニズムを提供します。

68.7.1 DISABLEプロシージャ

このプロシージャは、セッション全体においてフラッシュバック・モードを無効化します。

構文

DBMS_FLASHBACK.DISABLE;

次の例では、従業員Joeの2000年8月30日時点での給与を問い合せています。

EXECUTE dbms_flashback.enable_at_time('30-AUG-2000');
SELECT salary FROM emp where name = 'Joe'
EXECUTE dbms_flashback.disable;

68.7.2 ENABLE_AT_SYSTEM_CHANGE_NUMBERプロシージャ

このプロシージャは、SCNを入力パラメータとして使用し、セッションのスナップショットを指定した数値に設定します。

フラッシュバック・モードでは、すべての問合せにおいて、指定した実時間またはSCNの時点と一致したデータが戻されます。セッション全体においてフラッシュバックを使用できるようにします。

構文

DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER (
   query_scn IN NUMBER);

パラメータ

表68-4 ENABLE_AT_SYSTEM_CHANGE_NUMBERプロシージャのパラメータ

パラメータ 説明

query_scn

システム変更番号(SCN)。トランザクションのコミットごとに増分するデータベースのバージョン・ナンバーです。

68.7.3 ENABLE_AT_TIMEプロシージャ

このプロシージャは、セッション全体においてフラッシュバックを使用できるようにします。

スナップショット・タイムは、query_time.で指定された時間に最も近いSCNに設定されます。セッション全体においてフラッシュバックを使用できるようにします。

構文

DBMS_FLASHBACK.ENABLE_AT_TIME (
   query_time   IN TIMESTAMP);

パラメータ

表68-5 ENABLE_AT_TIMEプロシージャのパラメータ

パラメータ 説明

query_time

これは、TIMESTAMPタイプの入力パラメータです。タイム・スタンプは次の方法で指定できます。

  • TIMESTAMPコンストラクタの使用。

    EXECUTE DBMS_FLASHBACK.ENABLE_AT_TIME(TIMESTAMP '2001-01-09 12:31:00'). 

    グローバリゼーション・サポート(NLS)フォーマットを使用し、文字列を指定します。フォーマットは、グローバリゼーション・サポートの設定により異なります。

  • TO_TIMESTAMPファンクションの使用。

    EXECUTE DBMS_FLASHBACK.ENABLE_AT_TIME(TO_TIMESTAMP('12-02-2001 14:35:00', 'DD-MM-YYYY HH24:MI:SS'))

    使用する書式を指定します。この例では、2001年2月12日午後2時35分のTO_TIMESTAMPファンクションを示しています。

  • 問合せ時間から時間が省略された場合、デフォルトはその日の午前12時となります。

  • 問合せ時間にタイム・ゾーンが含まれる場合、タイム・ゾーンの情報は切り捨てられるので注意してください。

68.7.4 GET_SYSTEM_CHANGE_NUMBERファンクション

このファンクションは、現在のSCNをOracleの数値データ・タイプとして戻します。現行の変更番号を取得し、後で使用するために保存できます。これは特定のスナップショットの保存に便利です。

構文

DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER
 RETURN NUMBER;

68.7.5 TRANSACTION_BACKOUTプロシージャ

このプロシージャは、一連のトランザクションをバックアウトするためのメカニズムを提供します。ユーザーは、トランザクション名またはトランザクション識別子(XIDS)のいずれかを指定して、これらのプロシージャをコールできます。

このプロシージャは、トランザクションの依存性の分析、DMLの実行およびサブプログラムで実行された操作に対する広範囲なレポートの生成を行います。このプロシージャは、トランザクション・バックアウトの一部として実行されたDMLはコミットしません。ただし、行および表に対する必要なロックを正しい形式で保持するため、他の依存性がシステムに入力されることはありません。変更を永続的なものにするには、明示的にトランザクションをコミットする必要があります。

システム表DBA_FLASHBACK_TRANSACTION_STATEおよびDBA_FLASHBACK_TRANSACTION_REPORTにレポートが生成されます。

構文

DBMS_FLASHBACK.TRANSACTION_BACKOUT
   numtxns            NUMBER,
   xids               XID_ARRAY,
   options            NUMBER default NOCASCADE, 
   timeHint           TIMESTAMP default MINTIME);

DBMS_FLASHBACK.TRANSACTION_BACKOUT
   numtxns            NUMBER,  
   xids               XID_ARRAY, 
   options            NUMBER default NOCASCADE,
   scnHint            TIMESTAMP default 0   );

DBMS_FLASHBACK.TRANSACTION_BACKOUT
   numtxns           NUMBER,
   txnnames          TXNAME_ARRAY,
   options           NUMBER default NOCASCADE,
   timehint          TIMESTAMP MINTIME );

DBMS_FLASHBACK.TRANSACTION_BACKOUT
   numtxns           NUMBER, 
   txnNames         TXNAME_ARRAY, 
   options          NUMBER default NOCASCADE,
   scnHint          NUMBER 0);

パラメータ

表68-6 TRANSACTION_BACKOUTプロシージャのパラメータ

パラメータ 説明

numtxns

入力として渡されたトランザクションの数。

xids

配列の形式でのトランザクション識別子のリスト。

txnnames

配列の形式でのトランザクション名のリスト。

options

次のように、依存しているトランザクションをバックアウトします。

  • NOCASCADE: 依存性は期待されていません。依存性が検出された場合は、エラーが発生し、最初の依存トランザクションがレポートに表示されます。

  • NOCASCADE_FORCE: ユーザーは、依存トランザクションを考慮せずに、指定したトランザクションを強制的にバックアウトします。RDBMSによって、指定したトランザクションに対して、コミット時と逆の順序でUNDO SQLが実行されます。制約違反がなく、結果に問題がない場合、ユーザーは、変更をコミット(COMMIT)するか、またはロールバック(ROLL BACK)します。

  • NONCONFLICT_ONLY: このオプションを使用すると、指定したトランザクションの競合が発生していない行に対する変更をバックアウトできます。トランザクションの依存性は、WAWまたは主キー制約/一意キー制約による行の競合が原因で発生する可能性があります。競合が発生していない行のみのバックアウトをユーザーが選択した場合は、データベースの一貫性に問題が発生することはありませんが、トランザクションの原子性は失われます。これはリカバリ操作であるため、ユーザーはデータを修正できます。

  • CASCADE: 指定したトランザクションおよびその依存性を後順(コミット時の逆の順序)で完全に削除します。

timehint

トランザクションの開始に関する時間ヒント。

scnhint

トランザクションの開始に関するSCNヒント。

使用上のノート

ノート:

TRANSACTION_BACKOUTを使用する際の制限については、『Oracle Database開発ガイド』フラッシュバック・トランザクションの使用に関する項を参照してください。

  • トランザクション名を使用する場合は、時間ヒントを指定する必要があります。時間ヒントは、指定したすべてのトランザクションがバックアウトを開始する前の時間にする必要があります。

  • SCNヒントを指定する場合、その値は、指定した入力セット内で最も古いトランザクションの開始前にする必要があり、それ以外の値では、エラーが発生してプロシージャが終了します。指定せず、トランザクションがUNDO保存内でコミットされた場合は、データベース・システムで開始時刻を特定できます。