🔄 UNDOとは?
Oracle Databaseは、以下の目的で「UNDOデータ(元の値)」を使用します:
-
トランザクションのロールバック
-
一貫性のある読み取り(Read Consistency)
-
Oracle Flashback Query(過去の状態を参照する機能)
-
障害時リカバリ
🧠 UNDOの仕組み
-
Oracleはデータを変更する前の**元の値(UNDOデータ)**を保存。
-
このUNDOは、トランザクションがコミットされるまで上書きされない。
-
つまり、変更を**「お試し」感覚で行える**。
-
他のユーザーには見えず、自分だけが確認できる。
-
気に入れば
COMMIT
で確定。 -
気に入らなければ
ROLLBACK
で元に戻せる。
-
💻 デモの例
-
2つのセッションで同じデータを確認(例:従業員ID 100 の給与)。
-
一方のセッションで給与を更新(
UPDATE
)。 -
コミット前なので、他方のセッションでは元の給与が見える(一貫性のある読み取り)。
-
COMMIT
を実行すると、他のセッションでも変更が見えるようになる。
⚠️ 障害時のUNDOの役割
-
トランザクション中に:
-
ネットワーク障害やクライアントPCのクラッシュ
-
インスタンスクラッシュや
SHUTDOWN ABORT
の実行
-
-
こうした異常終了時は、自動的にUNDOデータでロールバックが行われる。
🧪 ロールバックの実例
-
給与を1人だけ下げるつもりが、全従業員107人の給与を下げてしまった。
-
ROLLBACK
を使ってUNDOデータから変更前の状態に戻せた。
⏳ UNDOデータの保持期間
-
UNDOはトランザクションが終了するまで必ず保持される。
-
保持時間や容量は、データベースの負荷や設定に依存。
🔁 UNDOとREDOの役割の違い
項目 | UNDO(アンドゥ) | REDO(リドゥ) |
---|---|---|
目的 | 変更を取り消す(ロールバック)ため | 変更を再実行(ロールフォワード)するため |
使用される時 | ユーザーがROLLBACK した時やセッション障害 | 電源障害などで変更が失われたとき |
🔄 UNDOの流れ
-
トランザクションが
COMMIT
される前 に、Oracleは UNDO情報(旧データ) を生成。 -
これは、ユーザーが変更を取り消す可能性に備えて保持される。
-
たとえば:
-
ROLLBACK
をしたとき -
セッションが異常終了したとき
-
-
OracleはこのUNDOを使って変更を元に戻す(ロールバック)。
🔁 REDOの流れ
-
COMMIT
処理の際は、変更内容が REDOログファイル(ディスク上)に書き込まれたかを確認。 -
REDOログへの書き込みが完了すれば、たとえデータファイル(表の実データ)にまだ反映されていなくても、
-
トランザクションは「確定済み(コミット済み)」と見なされる。
-
-
たとえば:
-
電源障害でOSが落ちたが、REDOログに記録されていれば
-
再起動時に、REDOログから変更を反映させてロールフォワードできる
✅ 読み取り一貫性
-
読み取り一貫性(Read Consistent Queries) とは、
クエリが開始された時点のデータを基準にして、一貫した結果を返す仕組みです。
🕒 具体例で説明:
-
たとえば、あなたのクエリが 時刻 T0 に開始 され、30分間実行されるとします。
-
他のユーザーが 時刻 T5 にデータを更新してコミットしても、
-
あなたのクエリは、T0時点のデータをT30まで表示し続けます。
-
なぜなら、Oracleは Undo情報(変更前のデータ) を使って、
クエリ開始時点の状態を再構築できるからです。
⚠️ 注意点:Undo情報の保持期間
-
ただし、他のユーザーが 頻繁にコミットしていると、
-
古いUndo情報が上書きされて消える可能性があります。
-
-
この場合、あなたのクエリが更新された行に遅れてアクセスしたときに、
-
Undo情報がもう存在していないことがあります。
-
その結果、**ORA-01555: snapshot too old(スナップショットが古すぎる)**というエラーが発生する可能性があります。
✅ Oracle Flashback Query の使い方と仕組み
📌 Flashback Query とは?
-
Oracleの Flashback Query を使うと、過去のある時点のデータ(コミット済み) を取り出すことができます。
-
他のフラッシュバック機能と同様に、Undo表領域 を利用して過去の状態を参照します。
-
時刻(timestamp)または SCN(System Change Number) を指定することで、その時点の状態を再現できます。
🔧 Flashback Query の準備
-
アーカイブログモードを有効化(未設定なら)
-
archive log list
で確認 -
有効化手順:
-
データベースを シャットダウン
-
MOUNT モードで起動
-
alter database archivelog;
でアーカイブログモードに変更 -
データベースを再オープン
-
-
-
Flashback機能の有効化
-
alter database flashback on;
を実行
-
🧪 使用例(Monicaのケース)
-
問題発生:12時、HRアプリ開発者が US_STATES テーブルの全データを誤って削除し、コミット。
-
対応方法:
-
Monicaは Flashback Query を使って削除前のデータを復元。
-
実験ステップ:
-
US_STATES テーブルを作成し、データ挿入。
-
少し時間を置いてからデータを削除。
-
SELECT * FROM US_STATES AS OF TIMESTAMP TO_TIMESTAMP('2025-07-09 06:15:00', 'YYYY-MM-DD HH24:MI:SS')
を使用して、削除前の状態を参照。 -
または
AS OF SCN <SCN番号>
を使って、特定の変更時点を指定。 -
データ復元には
INSERT INTO SELECT
を使用可能。
🧠 SCN(System Change Number)とは?
-
Oracle 内部の「時計」のようなもので、トランザクションの整合性のある時点を識別。
-
SELECT CURRENT_SCN FROM V$DATABASE
で現在のSCNを取得。 -
TIMESTAMP_TO_SCN()
やSCN_TO_TIMESTAMP()
関数で変換可能。
💡 注意点
項目 | 内容 |
---|---|
使用条件 | アーカイブログモードが有効であること |
データ復元 | INSERT INTO + Flashback Query が可能 |
Undo保持期間 | 過去の時点情報は Undo に依存するため、保持設定が重要 |
✅ ローカル Undo 管理(Oracle Multi-Tenant 環境)
🏗 Undoの2つのモード(マルチテナント構成)
-
共有(Shared)Undoモード:
CDBのroot
に1つの共通Undo表領域のみを使用。 -
ローカル(Local)Undoモード(推奨):
各PDBに1つのローカルUndo表領域を持つ。
※以下の操作時に必須:-
ホットクローン(稼働中クローン)
-
ダウンタイムほぼゼロでのPDB移動
-
PDBのリフレッシュやリストア
-
Proxy PDBの使用
-
⚙ Undoの管理方法(Automatic Undo Management)
-
undo_management
パラメータがAUTO
またはNULL
→ 自動Undo管理が有効(デフォルト) -
OracleがUndo表領域とUndoセグメントの管理を自動化。
-
Undo表領域は「自動エクステント管理されたローカル管理表領域」。
🗂 Undo表領域の確認・作成・切り替え
-
確認方法:
-
dba_tablespaces
ビューでcontents = 'UNDO'
の行を確認 -
dba_data_files
ビューで該当のファイルを確認
-
-
新規作成例:
-
有効なUndo表領域の確認:
-
切り替え方法(undo_tbs2 を有効に):
-
削除例(不要なUndo表領域):
🔍 Undoの状態(v$undostat
, dba_undo_extents
)
-
Undoセグメントの各エクステントのステータス:
ステータス 内容 ACTIVE 実行中トランザクションで使用中(上書き不可) UNEXPIRED コミット済だが保持期間内(可能なら保持) EXPIRED 保持期間終了(上書き可能) v$undostat
ビュー:過去のUndo使用状況を確認可能。
⏱ Undo保持期間(Undo Retention)
-
初期設定:
UNDO_RETENTION = 900
秒(15分) -
保持期間は、最長のクエリ時間を少し超えるように自動調整される(自動拡張時)。
-
設定変更例:
-
注意点:
-
保持期間を長くしすぎると、Undo表領域の空き不足で問題が起こる。
-
空きが不足すると、UNEXPIREDなUndoも再利用されてしまい、エラー(
ORA-01555: snapshot too old
)の原因に。
-
🛡 Undo Retention Guarantee(保持保証)
-
通常は、トランザクションを失敗させないために UNEXPIREDなUndoも上書きされる。
-
RETENTION GUARANTEE
を指定することで、保持期間を強制的に保証できる。-
設定例:
-
解除例:
-