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';
結果例:
XID | OPERATION | UNDO_SQL |
---|---|---|
03001200F5050000 | UPDATE | UPDATE “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情報が残っている期間内であれば、トランザクション単位での復旧が可能です。
日々の運用で不測の事態に備え、ぜひこの機能を覚えておきましょう!
[参考]
バックアップおよびリカバリ・ユーザーズ・ガイド
コメント