| Oracle Database アプリケーション開発者ガイド-基礎編 10gリリース2(10.2) B19248-02 |
|
この章の内容は次のとおりです。
Oracle Databaseには、総称してフラッシュバックと呼ばれる機能のグループがあり、Point-in-Timeメディア・リカバリを使用しなくても、データベース・オブジェクトの過去の状態を表示したり、データベース・オブジェクトを前の状態に戻すことができます。
データベースのフラッシュバック機能は、次の目的に使用できます。
フラッシュバック機能では、自動UNDO管理システムにより、トランザクションに関するメタデータおよび履歴データが取得されます。フラッシュバック機能はUNDOデータに依存します。UNDOデータは、個々のトランザクションの結果のレコードです。たとえば、ユーザーが給与を1000から1100に変更するUPDATE文を実行すると、UNDOデータに値1000が格納されます。
UNDOデータは永続的であり、データベース停止時にも失われません。フラッシュバック機能を使用すると、UNDOデータを使用して過去のデータを問い合せたり、論理的な破損からリカバリできます。UNDOデータは、フラッシュバック操作以外にも、Oracle Databaseによって次の処理に使用されます
アプリケーション開発では、フラッシュバック機能を使用して、履歴データに関するレポートを作成したり、誤った変更を元に戻すことができます。フラッシュバック機能には次のものが含まれます。
この機能を使用して、SELECT文のAS OF句で指定した過去のある時点のデータを取得できます。
この機能は、特定の時間間隔のメタデータおよび履歴データを取得する場合に使用します。たとえば、ある表の、特定の時間間隔内に存在していたすべての行を表示できます。様々なバージョンの行に関するメタデータには、開始時間と終了時間、変更処理のタイプおよび行バージョンを作成したトランザクションの識別情報が含まれます。フラッシュバック・バージョン問合せを作成するには、SELECT文のVERSIONS BETWEEN句を使用します。
この機能を使用して、特定の時間間隔内における特定のトランザクションまたはすべてのトランザクションのメタデータおよび履歴データを取得できます。また、SQLコードを取得して、トランザクションにより影響を受けた特定の行への変更を元に戻すことができます。通常、フラッシュバック・トランザクション問合せは、対象となる行のトランザクションIDを戻すフラッシュバック・バージョン問合せと併用します。フラッシュバック・トランザクション問合せを実行するには、FLASHBACK_TRANSACTION_QUERYビューから選択します。
DBMS_FLASHBACKパッケージその時点の最新データを検査できるように、Oracle内部の時計を過去のある時点まで戻す場合、この機能を使用できます。
アプリケーション開発または対話形式で、データベース・ユーザーまたは管理者として、次の機能を使用できます。
次のフラッシュバック機能は、通常はデータベース管理においてのみ使用します。
表の状態を以前の特定の時点までリカバリする場合、この機能を使用できます。データベースがオンラインの間は表のデータのリストアが可能であり、指定した表に対する変更のみ元に戻すことができます。
削除された表をリカバリする場合、この機能を使用できます。これによって、DROP TABLE文の影響が無効になります。
以前の特定の時点からのすべての変更を元に戻し、データベースをその時点まで迅速に戻します。データベースのバックアップをリストアする必要がないため、処理が高速です。
Oracle Flashback Database、Oracle Flashback TableおよびOracle Flashback Dropは、主にデータ・リカバリのメカニズムであるため、詳細は他のドキュメントで説明されています。その他のフラッシュバック機能は、データ・リカバリでも重要なものですが、アプリケーション開発にも便利な機能です。この章ではこれらの機能について説明します。
アプリケーションでフラッシュバック機能を使用するには、まず、次の管理タスクを実行してデータベースを構成する必要があります。これらのタスクを実行するには、データベース管理者に相談してください。
固定サイズのUNDO表領域の場合、Oracle Databaseでは次の処理が自動的に実行されます。
自動的に拡張可能なUNDO領域の場合、Oracle Databaseでは、最長の問合せ期間よりも長いUNDOデータ、およびUNDO_RETENTIONパラメータで指定されたUNDO保持の低いしきい値が保持されます。
RETENTION GUARANTEE句を指定して、期限切れになっていないUNDOが廃棄されないようにします。UNDO_RETENTIONの設定だけでは厳密な保証にはなりません。システムの領域が不十分な場合、期限切れになっていないUNDOが新しく生成されたUNDOによって上書きされる場合があります。RETENTION GUARANTEEを指定すると、この動作を防ぐことができます。
DBMS_FLASHBACKパッケージ: DBMS_FLASHBACKのEXECUTE権限を付与し、このパッケージの機能にアクセスできるようにします。
FLASHBACK権限およびSELECT権限を付与するか、またはすべての表に対する問合せを可能にするFLASHBACK ANY TABLE権限を付与します。
SELECT ANY TRANSACTION権限を付与します。
SELECT、UPDATE、DELETEおよびINSERT権限を必要に応じて付与し、Oracle Flashback Transaction Queryにより取得されたUNDO SQLコードの実行を許可します。
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
LOB列に対するフラッシュバック操作を可能にするには、ALTER TABLEコマンドをRETENTIONオプションとともに使用します。LOB列のUNDOデータは膨大になる場合があるため、フラッシュバック操作で使用するLOB列を定義する必要があります。フラッシュバック問合せは、SELECT文でAS OF句を使用して実行します。フラッシュバック問合せを使用すると、過去のある時点で存在していたデータを取得できます。問合せでは、タイムスタンプまたはSCNを使用することで、過去の時点が明示的に参照されます。その時点で最新であったコミット済データが戻されます。
フラッシュバック問合せは、次のような場合に使用します。
この例では、フラッシュバック問合せを使用して、以前の時点での表の状態を調べます。たとえば、DBAが午後12時30分に、従業員Chungの行がemployee表から削除されていることに気付いたとします。また、このDBAが、午前9時30分にはChungのデータがデータベースに正しく格納されていたことを知っているとします。DBAは、フラッシュバック問合せを使用して9時30分時点の表の内容を調べ、失われたデータを見つけることができます。その後必要に応じて、DBAは失われたデータを再挿入できます。
例10-1では、2004年4月4日午前9時30分におけるChungのレコードの状態が取得されます。
SELECT * FROM employees AS OF TIMESTAMP TO_TIMESTAMP('2004-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS') WHERE last_name = 'Chung';
例10-2の更新により、Chungの情報がemployees表にリストアされます。
INSERT INTO employees (SELECT * FROM employees AS OF TIMESTAMP TO_TIMESTAMP('2004-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS') WHERE last_name = 'Chung');
フラッシュバック問合せ(SELECT ...AS OF)を使用する場合、次の点に注意してください。
AS OF句を指定または省略できます。また、異なる表に異なる時間を指定できます。問合せと同じセッションで、表の作成、切捨てなどのDDL操作または挿入、削除などのDML操作を実行するには、問合せでAS OF句を使用します。
INSERT文またはCREATE TABLE AS SELECT文内でAS OF句を使用します。
SELECT文のAS OF句を使用して、過去のデータを参照するビューを作成できます。データベース・ホストの現在の時間から引いて相対時間を指定すると、過去の時間が各問合せで再計算されます。次に例を示します。
CREATE VIEW hour_ago AS SELECT * FROM employees AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '60' MINUTE); -- SYSTIMESTAMP refers to the time zone of the database host environment
INTERSECT、MINUSなど)のAS OF句は、2つの異なる時間のデータを抽出または比較するために使用できます。フラッシュバック問合せの前にCREATE TABLE AS SELECT文またはINSERT INTO TABLE SELECT文を置くことで、結果を格納できます。たとえば、次の問合せでは、1時間前に存在していた行がemployees表に再挿入されます。
INSERT INTO employees (SELECT * FROM employees AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '60' MINUTE)) -- SYSTIMESTAMP refers to the time zone of the database host environment MINUS SELECT * FROM employees);
DBMS_FLASHBACKパッケージでも、一般にフラッシュバック問合せと同じ機能が提供されますが、フラッシュバック問合せのほうが便利な場合があります。
DBMS_FLASHBACKパッケージはタイムマシンのように機能します。つまり、時計を特定の時点に戻して、過去のその時点にいるかのように通常の問合せを実行し、その後現在に戻ることができます。DBMS_FLASHBACKパッケージを使用して、AS OFやVERSIONS BETWEENなどの特別な句を使用せずに過去のデータに問合せを実行できるため、既存のPL/SQLコードを再使用して、過去の時点のデータベースを問い合せることができます。
DBMS_FLASHBACKパッケージのEXECUTE権限が必要です。
PL/SQLコードでDBMS_FLASHBACKパッケージを使用する手順は、次のとおりです。
DBMS_FLASHBACK.ENABLE_AT_TIMEまたはDBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBERをコールし、過去の指定された時点まで時計を戻します。この後、すべての問合せで、指定された時間の最新データが取得されます。
AS OFなど、特別なフラッシュバック機能の構文を使用しない)を実行します。指定された過去の時間におけるデータベースに対し、問合せが自動的に行われます。問合せのみ実行し、DDL操作やDML操作は実行しないでください。
DBMS_FLASHBACK.DISABLEをコールし、現在に戻ります。別の時間について再度ENABLEをコールする前に、DISABLEをコールする必要があります。ENABLE / DISABLEのペアはネストできません。
カーソルを使用して、問合せの結果を格納できます。そのためには、DBMS_FLASHBACK.DISABLEをコールする前に、カーソルをオープンします。結果を格納し、DISABLEをコールした後、次のことができます。
INSERTまたはUPDATE操作を実行し、過去のデータベースの格納結果を使用して現在のデータベースの状態を変更します。
DISABLEをコールした後、2番目のカーソルをオープンします。過去のデータを取得するには最初のカーソルからフェッチし、現在のデータを取得するには2番目のカーソルからフェッチします。過去のデータを一時表に格納し、その後MINUSやUNIONなどの集合演算子を使用して、過去のデータと現在のデータを比較または結合できます。
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBERをコールして、いつでも現在のシステム変更番号(SCN)を取得できます。必ず現在のSCNが戻される点に注意してください。DBMS_FLASHBACK.ENABLE*に対する以前のコールは無視されます。
ORA_ROWSCNは、固定されていない、または外部表ではない表の疑似列です。これは、指定された行に対する最新の変更のSCNを表します。つまり、その行に対する最新のCOMMIT操作です。次に例を示します。
SELECT ora_rowscn, last_name, salary FROM employees WHERE employee_id = 7788; ORA_ROWSCN NAME SALARY ---------- ---- ------ 202553 Fudd 3000
その行に対する最新のCOMMIT操作は、SCNが202553ほどのところで発生しています。SCN_TO_TIMESTAMPファンクションを使用して、ORA_ROWSCNのようなSCNを、対応するTIMESTAMP値に変換できます。
ORA_SCNは、実際は最新コミット時間の堅実な上限値であり、実際のコミットSCNはこれより若干前になる場合があります。行に依存する表(CREATE TABLEをROWDEPENDENCIES句と併用して作成)では、ORA_SCNはより正確になります(実際のコミットSCNに近づきます)。
アプリケーション開発においてORA_ROWSCNを使用することの特に有益な点は、同時実行性制御およびクライアント・キャッシュの無効化があります。同時実行性制御におけるORA_ROWSCNの使用方法について、次の使用例を考えてみます。
アプリケーションでデータ行が検査され、対応するORA_ROWSCNが202553として記録されます。その後、このアプリケーションでは、データのレコードが正確である場合のみ、行を更新する必要があります。つまり、この特定の更新操作は、変更されていない行に論理的に依存します。したがって、この操作は、ORA_ROWSCNがまだ202553であることが条件となります。次に、同等の対話型コマンドを示します。
UPDATE employees SET salary = salary + 100 WHERE employee_id = 7788 AND ora_rowscn = 202553; 0 rows updated.
この場合、ORA_ROWSCNがすでに202553ではないため、条件付きの更新に失敗します。これは、記録されているORA_ROWSCNよりも最近、ユーザーまたは他のアプリケーションにより行が変更され、COMMITが実行されたことを意味します。
アプリケーションでは、新しい行データおよびORA_ROWSCNを取得するため、再度問合せが実行されます。ORA_ROWSCNが現在415639であるとします。アプリケーションでは、新しいORA_ROWSCNにより、再度条件付き更新が試行されます。今回は更新に成功し、コミットされました。次に、同等の対話型コマンドを示します。
SQL> UPDATE employees SET salary = salary + 100 WHERE empno = 7788 AND ora_rowscn = 415639; 1 row updated. SQL> COMMIT; Commit complete. SQL> SELECT ora_rowscn, name, salary FROM employees WHERE empno = 7788; ORA_ROWSCN NAME SALARY ---------- ---- ------ 465461 Fudd 3100
新しいCOMMITに対応するSCNは、465461です。
UPDATE文のWHERE句でORA_ROWSCNを使用するだけでなく、DELETE文のWHERE句またはフラッシュバック問合せのAS OF句で使用できます。
特定の時間間隔内に存在していた、特定の行の様々なバージョンを取得するには、フラッシュバック・バージョン問合せを使用します。COMMIT文が実行されると、そのたびに新しい行バージョンが作成されます。
フラッシュバック・バージョン問合せを指定するには、SELECT文でVERSIONS BETWEEN句を使用します。その構文を次に示します。
VERSIONS {BETWEEN {SCN | TIMESTAMP}startANDend}
ここで、startおよびendはそれぞれ、問合せ対象の時間間隔の開始点と終了点を表す式です。この時間間隔はその両端でクローズします。つまり、指定された上限および下限(startおよびend)は、どちらも時間間隔に含まれます。
フラッシュバック・バージョン問合せでは、特定の行について、指定した時間間隔内に存在していたすべてのバージョンの各1行を含む表が戻されます。表の各行には、行バージョンに関するメタデータの疑似列が含まれます。これについては表10-1で説明しています。この情報により、特定の変更(誤った変更など)がデータベースにいつ、どのように加えられたかがわかります。
指定された行バージョンは、VERSIONS_START*の時間からVERSIONS_END*の時間(ただしこの時間は含まれない)まで有効です。つまり、VERSIONS_START* <= t < VERSIONS_END*である場合、時間tではいつでも有効です。たとえば、次の出力は、2002年9月9日(この日付を含む)から2003年11月25日(この日付は含まない)まで、給与が10243であったことを示します。
VERSIONS_START_TIME VERSIONS_END_TIME SALARY ------------------- ----------------- ------ 09-SEP-2003 25-NOV-2003 10243
次に、一般的なフラッシュバック・バージョン問合せを示します。
SELECT versions_startscn, versions_starttime, versions_endscn, versions_endtime, versions_xid, versions_operation, name, salary FROM employees VERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP('2003-07-18 14:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2003-07-18 17:00:00', 'YYYY-MM-DD HH24:MI:SS') WHERE name = 'JOE';
疑似列VERSIONS_XIDは、データをその状態にしたトランザクションに、一意の識別子を提供します。この値をフラッシュバック・トランザクション問合せと併せて使用して、FLASHBACK_TRANSACTION_QUERYビューで、行の変更を元に戻すために必要なSQLおよびその変更の担当ユーザーなど、このトランザクションに関するメタデータを検索できます。「フラッシュバック・トランザクション問合せの使用」を参照してください。
フラッシュバック・トランザクション問合せは、FLASHBACK_TRANSACTION_QUERYビューに対する問合せです。そのトランザクションによる各変更を元に戻す際に使用できるSQLコードなど、トランザクション情報を取得するには、フラッシュバック・トランザクション問合せを使用します。
一例として、次の文では、トランザクションID、操作、操作の開始SCNおよび終了SCN、操作の担当ユーザーおよび操作を元に戻すためのSQLコードなどのトランザクション情報について、FLASHBACK_TRANSACTION_QUERYビューを問い合せています。
SELECT xid, operation, start_scn,commit_scn, logon_user, undo_sql FROM flashback_transaction_query WHERE xid = HEXTORAW('000200030000002D');
もう一つの例として、次の問合せでは、フラッシュバック・バージョン問合せを副問合せとして使用し、各行バージョンを、行データの変更を担当するLOGON_USERに関連付けています。
SELECT xid, logon_user FROM flashback_transaction_query WHERE xid IN (SELECT versions_xid FROM employees VERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP('2003-07-18 14:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2003-07-18 17:00:00', 'YYYY-MM-DD HH24:MI:SS'));
この例は、フラッシュバック・トランザクション問合せとフラッシュバック・バージョン問合せの併用を示します。この例では、サンプルのhrスキーマにおけるemployeesおよびdepartments表の単純な変化が想定されています。
この例では、DBAがSQL*Plusで次の一連のアクションを実行しています。
connect hr/hr CREATE TABLE emp (empno NUMBER PRIMARY KEY, empname VARCHAR2(16), salary NUMBER); INSERT INTO emp VALUES (111, 'Mike', 555); COMMIT; CREATE TABLE dept (deptno NUMBER, deptname VARCHAR2(32)); INSERT INTO dept VALUES (10, 'Accounting'); COMMIT;
この時点で、empおよびdeptにはそれぞれ1行があります。行バージョンに関しては、各表に1つのバージョンを示す1行が含まれます。次に、誤ったトランザクションにより、従業員ID111がemp表から削除されたとします。
UPDATE emp SET salary = salary + 100 WHERE empno = 111; INSERT INTO dept VALUES (20, 'Finance'); DELETE FROM emp WHERE empno = 111; COMMIT;
その後、新規トランザクションにより、従業員ID111および新規従業員名がemp表に再挿入されます。
INSERT INTO emp VALUES (111, 'Tom', 777); UPDATE emp SET salary = salary + 100 WHERE empno = 111; UPDATE emp SET salary = salary + 50 WHERE empno = 111; COMMIT;
この時点で、DBAはアプリケーション・エラーを検出したため、問題を診断する必要があります。DBAは次の問合せを発行し、従業員番号111に対応するemp表の行のバージョンを取得します。この問合せでは、フラッシュバック・バージョン問合せの疑似列が使用されます。
connect dba_name/password SELECT versions_xid XID, versions_startscn START_SCN, versions_endscn END_SCN, versions_operation OPERATION, empname, salary FROM hr.emp VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE where empno = 111; XID START_SCN END_SCN OPERATION EMPNAME SALARY ---------------- ---------- --------- ---------- ---------- ---------- 0004000700000058 113855 I Tom 927 000200030000002D 113564 D Mike 555 000200030000002E 112670 113564 I Mike 555 3 rows selected
結果表は、時間の経過順に下から上へ表示されます。3行目は、表が作成されたときに表に最初に挿入されたempの行のバージョンに対応しています。2行目は、誤ったトランザクションにより削除されたempの行に対応します。1行目は、新規従業員名とともに再挿入されたempの行のバージョンに対応します。
DBAは、トランザクション000200030000002Dを誤ったトランザクションとして識別し、次のフラッシュバック・トランザクション問合せを発行して、このトランザクションによるすべての変更を監査します。
SELECT xid, start_scn START, commit_scn COMMIT, operation OP, logon_user USER, undo_sql FROM flashback_transaction_query WHERE xid = HEXTORAW('000200030000002D'); XID START COMMIT OP USER UNDO_SQL ---------------- ----- ------ -- ---- --------------------------- 000200030000002D 195243 195244 DELETE HR insert into "HR"."EMP" ("EMPNO","EMPNAME","SALARY") values ('111','Mike','655'); 000200030000002D 195243 195244 INSERT HR delete from "HR"."DEPT" where ROWID = 'AAAKD4AABAAAJ3BAAB'; 000200030000002D 195243 195244 UPDATE HR update "HR"."EMP" set "SALARY" = '555' where ROWID = 'AAAKD2AABAAAJ29AAA'; 000200030000002D 195243 113565 BEGIN HR 4 rows selected
一番右の列(undo_sql)には、対応する変更操作を元に戻すSQLコードが含まれます。DBAはこのコードを実行し、そのトランザクションによる変更を元に戻すことができます。USER列(logon_user)は、トランザクションの担当ユーザーを示します。
DBAは、特定の時間帯におけるすべての変更を把握する必要がある場合もあります。この使用例では、DBAは、以前識別された誤ったトランザクション以降に実行されたすべてのトランザクション(誤ったトランザクション自体を含む)の詳細を表示するために、次の問合せを実行します。
SELECT xid, start_scn, commit_scn, operation, table_name, table_owner FROM flashback_transaction_query WHERE table_owner = 'HR' AND start_timestamp >= TO_TIMESTAMP ('2002-04-16 11:00:00','YYYY-MM-DD HH:MI:SS'); XID START_SCN COMMIT_SCN OPERATION TABLE_NAME TABLE_OWNER ---------------- --------- ---------- --------- ---------- ----------- 0004000700000058 195245 195246 UPDATE EMP HR 0004000700000058 195245 195246 UPDATE EMP HR 0004000700000058 195245 195246 INSERT EMP HR 000200030000002D 195243 195244 DELETE EMP HR 000200030000002D 195243 195244 INSERT DEPT HR 000200030000002D 195243 195244 UPDATE EMP HR 6 rows selected
次のヒントおよび制限は、フラッシュバック機能の使用に適用されます。
DBMS_STATSパッケージを使用して、フラッシュバック問合せに含まれるすべての表に統計情報を生成し、統計情報を現在の状態で保持します。フラッシュバック問合せは、常に、これらの統計情報に依存するコストベース・オプティマイザを使用します。
xid列の型がRAW(8)です。xid列に対して作成された索引を利用するには、HEXTORAW変換ファンクションHEXTORAW(xid)を使用します。
DBMS_FLASHBACKパッケージまたはその他のフラッシュバック機能を使用しますか?DBMS_FLASHBACKパッケージに対するENABLE/DISABLEコールを、制御しないSQLコード、または複数の連続した問合せに対し過去の同じ時刻を使用する場合のSQLコードの周辺で使用します。便宜上、記述するSQLには、フラッシュバック問合せ、フラッシュバック・バージョン問合せまたはフラッシュバック・トランザクション問合せを使用します。たとえば、フラッシュバック問合せは柔軟であるため、比較したり、単一の問合せに結果を格納できます。
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBERを使用します。
INTERVAL値をSYSTIMESTAMP関数に加算または減算すると、日時の計算ができます。
(SELECT * FROM employees@some_remote_host AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '60' MINUTE);
COMMITまたはROLLBACK操作を実行します。
PCTFREE、INITRANSおよびMAXTRANSなど)を変更するDDL操作には適用されません。
たとえば、SCN値1000および1005が、午前8時41分および8時46分にそれぞれマップされていると仮定します。午前8時41分00秒と8時45分59秒の間の時間に対する問合せは、SCN 1000にマップされ、午前8時46分に対するフラッシュバック問合せは、SCN 1005にマップされます。
このような時間とSCN値のマッピングによって、表の作成などのDDL操作の直後の時点を指定した場合、実際は、データベースではDDL操作の直前のSCNが使用される可能性があります。これによって、エラーORA-01466が発生する場合があります。
V$ビューから過去のデータは取得できません。このようなビューに問合せを実行すると、常に現在のデータを戻します。ただし、データ・ディクショナリの他のビュー(USER_TABLESなど)の過去のデータにも問合せを実行できます。
|
![]() Copyright © 2006 Oracle Corporation. All Rights Reserved. |
|