Oracle フラッシュバックバージョン問い合わせ(Flashback Version Query)

Oracle Master Gold

Oracle Databaseを運用していると、「いつ、どのトランザクションで、データがどう書き換えられたのか」という履歴を追跡したい場面があります。そんな時に役立つのがフラッシュバックバージョン問い合わせ(Flashback Version Query)です。

この機能を使えば、特定の行に対して過去に行われた挿入・更新・削除の変遷を、SCNや時間軸に沿って一覧表示できます。

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


1. フラッシュバックバージョン問い合わせとは?

フラッシュバックバージョン問い合わせは、UNDOデータを利用して特定の期間(SCNまたは日時)内に発生した行レベルの変更履歴を表示する機能です。通常の SELECT 文に VERSIONS BETWEEN 句を加えるだけで、変更の「開始点」「終了点」「操作内容(I/U/D)」をメタデータとともに取得できます。


2. 事前準備:テスト用テーブルの作成と履歴生成

実際に履歴を確認するために、テーブルを作成して複数回の更新を行ってみましょう。

① テーブル作成と初期データ投入

-- テスト用表の作成
CREATE TABLE emp_flash (
  emp_id    NUMBER PRIMARY KEY,
  emp_name  VARCHAR2(50),
  salary    NUMBER
);

-- 初期データの投入
INSERT INTO emp_flash VALUES (1, 'TARO', 300000);
COMMIT;

② リカバリポイント(現在のSCN)の確認

更新前の開始点となるSCNをメモしておきます。

-- 現在のSCNの確認
SELECT CURRENT_SCN FROM V$DATABASE;
-- 例: 2284694

③ データの更新とコミット

あえて複数回に分けてコミットし、変更履歴を生成します。

-- 1回目の更新
UPDATE emp_flash SET salary = 320000 WHERE emp_id = 1;
COMMIT;

-- 2回目の更新
UPDATE emp_flash SET salary = 350000 WHERE emp_id = 1;
COMMIT;

-- 3回目の更新
UPDATE emp_flash SET salary = 400000 WHERE emp_id = 1;
COMMIT;

-- 最終時点のSCNを確認
SELECT CURRENT_SCN FROM V$DATABASE;
-- 例: 2284735

3. 履歴の確認(SCN指定)

VERSIONS BETWEEN SCN を使用して、指定したSCNの範囲内でデータがどう変わったかを確認します。

SELECT 
  emp_id,
  emp_name,
  salary,
  VERSIONS_STARTSCN,  -- 変更が有効になった開始SCN
  VERSIONS_ENDSCN,    -- 変更が上書きされた終了SCN
  VERSIONS_XID,       -- トランザクションID
  VERSIONS_OPERATION  -- 操作種別 (I:Insert, U:Update, D:Delete)
FROM 
  emp_flash VERSIONS BETWEEN SCN 2284694 AND 2284735
WHERE 
  emp_id = 1;
SQL> CREATE TABLE emp_flash (
2 emp_id NUMBER PRIMARY KEY,
3 emp_name VARCHAR2(50),
4 salary NUMBER
5 );

表が作成されました。

SQL> INSERT INTO emp_flash VALUES (1, 'TARO', 300000);

1行が作成されました。

SQL> col emp_name for a20
SQL> SELECT * FROM emp_flash;

EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 300000

SQL> commit;

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

SQL> SELECT CURRENT_SCN FROM V$DATABASE;

CURRENT_SCN
-----------
2284694

SQL> UPDATE emp_flash SET salary = 320000 WHERE emp_id = 1;

1行が更新されました。

SQL> SELECT * FROM emp_flash;

EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 320000

SQL> commit;

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

SQL> UPDATE emp_flash SET salary = 350000 WHERE emp_id = 1;

1行が更新されました。

SQL> SELECT * FROM emp_flash;

EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 350000

SQL> commit;

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

SQL> UPDATE emp_flash SET salary = 400000 WHERE emp_id = 1;

1行が更新されました。

SQL> SELECT * FROM emp_flash;

EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 400000

SQL> commit;

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

SQL> SELECT CURRENT_SCN FROM V$DATABASE;

CURRENT_SCN
-----------
2284735

SQL> SELECT
2 emp_id,
3 emp_name,
4 salary,
5 VERSIONS_STARTSCN,
6 VERSIONS_ENDSCN,
7 VERSIONS_XID,
8 VERSIONS_OPERATION
9 FROM
10 emp_flash VERSIONS BETWEEN SCN 2284694 AND 2284735
11 WHERE
12 emp_id = 1;

EMP_ID EMP_NAME SALARY VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_XID VER
---------- -------------------- ---------- ----------------- --------------- ---------------- ---
1 TARO 400000 2284723 09000700F1030000 U
1 TARO 350000 2284710 2284723 08000C000E040000 U
1 TARO 320000 2284702 2284710 0A001A00FE030000 U
1 TARO 300000 2284702

実行結果のイメージ

EMP_IDEMP_NAMESALARYVERSIONS_STARTSCNVERSIONS_ENDSCNVERSIONS_OPERATION
1TARO4000002284723U
1TARO35000022847102284723U
1TARO32000022847022284710U
1TARO3000002284702

4. 日時で履歴を指定する方法(補足)

SCNの代わりに、人間にわかりやすい日時(TIMESTAMP)で指定することも可能です。

SELECT 
  emp_id,
  emp_name,
  salary,
  VERSIONS_STARTTIME,
  VERSIONS_ENDTIME,
  VERSIONS_OPERATION
FROM 
  emp_flash VERSIONS BETWEEN TIMESTAMP 
    TO_TIMESTAMP('2025-03-22 10:00:00', 'YYYY-MM-DD HH24:MI:SS') 
AND 
    TO_TIMESTAMP('2025-03-22 11:00:00', 'YYYY-MM-DD HH24:MI:SS')
WHERE 
  emp_id = 1;

5. FAQ

Q: VERSIONS_STARTSCN が null になっている行があるのはなぜですか?

A: その行の変更が、指定した BETWEEN 範囲よりも前に行われた場合に null となります。

Q: VERSIONS_OPERATION で取得できる文字の意味を教えてください。

A: I は INSERT、U は UPDATE、D は DELETE を示します。

Q: どのくらい前の履歴まで遡ることができますか?

A: UNDO表領域のサイズと UNDO_RETENTION パラメータの設定に依存します。これらを超えてデータが上書きされると参照できません。

Q: DDL(テーブル定義変更)を行った後の履歴はどうなりますか?

A: テーブル定義の変更を跨いでバージョン問い合わせを行うと、エラーが発生するか、正しい結果が得られない場合があります。


6. まとめ

項目内容
主な用途データの誤更新調査、監査、トラブルシューティング
必要なデータUNDOデータ(UNDO表領域に依存)
指定方法SCN(システム変更番号)または TIMESTAMP(日時)
取得情報変更前後の値、トランザクションID、操作種別(I/U/D)

フラッシュバックバージョン問い合わせは、特定のデータの「犯人探し」や「変遷の確認」に最適な機能です。本番環境で不審なデータを見つけた際は、まずこのクエリで歴史を紐解いてみましょう。

本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。


[参考]
Oracle Flashback Technologyの使用

フラッシュバック・データベースの構築手順と運用の極意
Oracle Databaseを運用する上で、最も強力な「保険」の一つがフラッシュバック・データベース(Flashback Database)です。 ユーザーが誤って大規模な更新を行ったり、アプリケーションのバグでデータが壊れたりした際、デ…
Oracle フラッシュバックテクノロジーとは?
〜誤操作からの救世主、Oracleの強力な巻き戻し機能を解説〜Oracle Databaseには、時間を巻き戻す魔法のような機能「フラッシュバックテクノロジー(Flashback Technology)」が備わっています。ユーザーが誤ってデ…

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

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