Oracleフラッシュバック・トランザクションの使い方

Oracle Master Gold

Oracleの「フラッシュバック・トランザクション(FLASHBACK TRANSACTION)」は、誤って行ったデータ変更を元に戻すためのとても便利な機能です。

本記事では、実際にテーブルを作成してトランザクションを実行し、フラッシュバックで元に戻す手順を図とSQL付きでわかりやすく解説します。


🔁 フラッシュバック・トランザクションとは?

特定のトランザクション単位で変更を取り消し、データを元の状態に戻せる機能です。

以下のような操作を誤って行った際に有効です。

  • DELETE, UPDATE, INSERTの誤操作
  • 誤ったデータを更新したアプリケーションの処理

📌 必要な前提条件

項目内容
自動UNDO管理UNDO_MANAGEMENT = AUTO
UNDO保持期間トランザクションのUNDO情報が残っていること
最小補助ログ有効である必要あり(後述のSQL参照)

📋 実践環境の準備

まずはテスト用のテーブルを作成し、初期データを挿入しましょう。

🔧 テーブル作成とデータ挿入

CREATE TABLE emp_test (
empno NUMBER PRIMARY KEY,
ename VARCHAR2(20),
sal NUMBER
);

INSERT INTO emp_test VALUES (1001, 'SCOTT', 3000);
INSERT INTO emp_test VALUES (1002, 'JONES', 2500);
COMMIT;

❌ 誤操作を実行(UPDATE文)

次に、誤って給料を0にしてしまったという状況を作ります。

UPDATE emp_test SET sal = 0 WHERE empno = 1001;
COMMIT;

🔍 トランザクションID(XID)を特定する

以下のSQLで、該当トランザクションのXIDを確認できます。

SELECT xid, operation, undo_sql, table_name, start_timestamp
FROM flashback_transaction_query
WHERE table_name = 'EMP_TEST';

結果例:

XIDOPERATIONUNDO_SQL
03001200F5050000UPDATEUPDATE “EMP_TEST” SET “SAL” = ‘3000’ WHERE…

このXIDを使って、元の状態に戻すことができます。


🔁 フラッシュバック・トランザクションの実行

以下のPL/SQLブロックを使ってトランザクションを元に戻します。

BEGIN
DBMS_FLASHBACK.TRANSACTION_BACKOUT(
numtxns => 1,
xids => SYS.XID_ARRAY('03001200F5050000'),
options => DBMS_FLASHBACK.CASCADE
);
END;
/
SQL> SELECT supplemental_log_data_min FROM v$database;

SUPPLEMENTAL_LOG_DATA_MI
------------------------
NO

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; ★最小サプリメンタルロギングを設定

データベースが変更されました。

SQL> SELECT supplemental_log_data_min FROM v$database;

SUPPLEMENTAL_LOG_DATA_MI
------------------------
YES

SQL> ALTER SYSTEM SWITCH LOGFILE;

システムが変更されました。

SQL> CREATE TABLE emp_test (
2 empno NUMBER PRIMARY KEY,
3 ename VARCHAR2(20),
4 sal NUMBER
5 );

表が作成されました。

SQL> INSERT INTO emp_test VALUES (1001, 'SCOTT', 3000);

1行が作成されました。

SQL> INSERT INTO emp_test VALUES (1002, 'JONES', 2500);

1行が作成されました。

SQL> SELECT * FROM emp_test;

EMPNO ENAME SAL
---------- ------------------------------ ----------
1001 SCOTT 3000
1002 JONES 2500

SQL> commit;

コミットが完了しました。

SQL> UPDATE emp_test SET sal = 0 WHERE empno = 1001; ★誤った処理を実行

1行が更新されました。

SQL> SELECT * FROM emp_test;

EMPNO ENAME SAL
---------- ------------------------------ ----------
1001 SCOTT 0
1002 JONES 2500

SQL> commit;

コミットが完了しました。

SQL> alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';

セッションが変更されました。

SQL> set linesize 1000
SQL> col operation for a10
SQL> col undo_sql for a80
SQL> col table_name for a10
SQL> SELECT xid, operation, undo_sql, table_name, start_timestamp
2 FROM flashback_transaction_query
3 WHERE table_name = 'EMP_TEST';

XID OPERATION UNDO_SQL TABLE_NAME START_TIMESTAMP
---------------- ---------- -------------------------------------------------------------------------------- ---------- -------------------
03001A00F7030000 INSERT delete from "TEST1"."EMP_TEST" where ROWID = 'AAASHRAAHAAAAF+AAB'; EMP_TEST 2025/03/23 11:24:50
03001A00F7030000 INSERT delete from "TEST1"."EMP_TEST" where ROWID = 'AAASHRAAHAAAAF+AAA'; EMP_TEST 2025/03/23 11:24:50
0800130000040000 UPDATE update "TEST1"."EMP_TEST" set "SAL" = '3000' where ROWID = 'AAASHRAAHAAAAF+AAA'; EMP_TEST 2025/03/23 11:25:26 ★この時点に戻す

SQL> conn / as sysdba
接続されました。
SQL> BEGIN
2 DBMS_FLASHBACK.TRANSACTION_BACKOUT(
3 numtxns => 1,
4 xids => SYS.XID_ARRAY('0800130000040000'), ★
5 options => DBMS_FLASHBACK.CASCADE
6 );
7 END;
8 /

PL/SQLプロシージャが正常に完了しました。

SQL> SELECT * FROM test1.emp_test;

EMPNO ENAME SAL
---------- ------------------------------ ----------
1001 SCOTT 3000 ★元の値に戻っている
1002 JONES 2500

オプションの意味

オプション説明
NOCASCADE依存トランザクションがあるとエラーになる
CASCADE依存トランザクションも一緒に取り消す
NOCASCADE_FORCE依存を無視して強制(非推奨)
NONCONFLICT_ONLY競合がないものだけ戻す

📌 サプリメンタルロギングを有効化していない場合

フラッシュバックを利用するには、サプリメンタルロギングが有効である必要があります。

確認と設定方法:

-- サプリメンタルロギングの確認
SELECT supplemental_log_data_min FROM v$database;

-- 有効でない場合の設定
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

🧷 依存トランザクションとは?

たとえば以下のようなトランザクションの流れがあった場合:

T1: emp_testのSAL=0に更新 ← 誤操作
T2: SAL=0の行をさらにUPDATE ← T1に依存

このように、T1を元に戻すには、T2も一緒に戻す必要があります。

T1──▶T2──▶T3(依存関係)

そのため、通常は CASCADE オプションを使って 依存トランザクションも一括で戻す のが安全です。


✅ まとめ

内容説明
対象誤ったトランザクションをUNDOしたいとき
方法DBMS_FLASHBACK.TRANSACTION_BACKOUTを使う
XIDの取得FLASHBACK_TRANSACTION_QUERYビューで確認
依存トランザクションCASCADEで一括取り消しが推奨

💬 最後に

フラッシュバック・トランザクションは、DELETEやUPDATEなどの誤操作を即座に取り消せる強力な機能です。UNDO情報が残っている期間内であれば、トランザクション単位での復旧が可能です。

日々の運用で不測の事態に備え、ぜひこの機能を覚えておきましょう!

[参考]
バックアップおよびリカバリ・ユーザーズ・ガイド

コメント

タイトルとURLをコピーしました