「コミットしたのにデータが消えた」と青ざめた経験がある方は少なくないはずです。REDOログの仕組みを理解しておくと、そうした場面での原因切り分けが格段に早くなります。

ACIDとトランザクション

トランザクションとREDO/UNDO図

図1: トランザクション処理とREDO/UNDO の役割

  • A — Atomicity 原子性: 全て成功するか、全てなかったことになるか。途中で死んでも整合性は保つ。
  • C — Consistency 一貫性: 整合性ルール(制約・チェック)を破った状態になる遷移を許さない。
  • I — Isolation 独立性: 同時に走る他のトランザクションから影響を受けない(分離レベルで強さを選ぶ)。
  • D — Durability 永続性: 一度コミットした内容は障害があっても失わない。⇒ REDOログがこの責務を担う

UNDOとREDOの役割

REDO「やり直しのための記録」

  • 全ての変更を「ブロックXに対する変更内容」として時系列で記録(シーケンシャル書き込み)。
  • コミット時は必ずディスクのREDOへ書く。
  • 障害でメモリ上の更新が失われた場合、REDOを再適用してデータを「やり直す」。
  • ファイル: オンライン + アーカイブ。

UNDO「やり直す前の姿」

  • 更新前の値を保管する。
  • ROLLBACK 実行時はここから戻す。
  • 他セッションが読むときの「コミット前は見せない」一貫性読み取りに使う。
  • 長いトランザクションはUNDOを圧迫し ORA-01555(snapshot too old)等の原因に。
覚え方: REDO = 「進む」/ UNDO = 「戻す」 どちらもログだが、目的が逆。

REDOログ書き込みの流れ

  1. UPDATE実行: サーバプロセスがバッファキャッシュ上のブロックを変更し、REDOログバッファに「変更ベクトル」を書く。
  2. COMMIT: セッションが COMMIT を発行。
  3. LGWR ⇒ ディスク: LGWRがREDOログバッファをオンラインREDOログ(ディスク)にフラッシュする。
  4. コミット完了応答: ディスク書込み完了をもってクライアントにOKを返す。
  5. DBWRは後追い: 実データファイルへの反映はDBWRが後で行う。途中で落ちてもREDOで再現可能。
コミット = REDOがディスクへ書かれた時点。COMMITが遅い時はLGWR/ストレージがボトルネックの可能性大。

チェックポイントとリカバリ

チェックポイント = 「この時点までの変更はデータファイルに反映済」と宣言する処理。

  • CKPTプロセスが定期的に発火し、DBWRに「ここまで書き出して」と促す。
  • データファイルのヘッダ・制御ファイルに到達した位置(SCN/LSN)を記録。

障害発生時のリカバリ

最新チェックポイント以降のREDOだけを再適用すれば良い ⇒ 起動時間に直結。

オンラインREDOとアーカイブREDO

オンラインREDOログ

最低2グループ以上を循環使用。各グループは多重化(同一内容を複数ファイル)が基本。満杯になると次のグループへ切替、最古は上書き。

アーカイブREDOログ

ARCHIVELOG モード時のみ。上書き前にコピーを取り、PITRやスタンバイDBに使う。

  • NOARCHIVELOG: オンラインREDOしか持たない。バックアップからの全リストア+再開のみ。簡易環境向け。
  • ARCHIVELOG: 全変更が永続的に残る。PITR(指定時点復旧)、スタンバイDB、論理レプリケーション等が可能。
REDO関連のパラメータは「ログバッファ」「ログサイズ」「多重化」「アーカイブ」の4観点で押さえると応用が利く。

開発者として知っておくべきREDOの実践Tips

DBの実装を理解していなくても、以下の観点を知っているだけで「なぜこの操作は遅いのか」「なぜこのエラーが出るのか」がわかるようになる。

シナリオ 原因 対処
COMMITが遅いLGWRがREDOをディスクに書くのが遅い(ストレージI/Oがボトルネック)REDOログを高速なSSDに配置、またはASMミラーリングの再検討
ORA-01555: snapshot too old長時間のトランザクションやSELECT中にUNDOが上書きされたUNDO_RETENTIONを延長、またはUNDO表領域を拡張
バルクINSERTが遅いREDOログが大量に生成されているNOLOGGING句(対象テーブルが許可している場合)またはDirect-Path Insertで削減
ROLLBACKが遅い大量更新後のロールバックはUNDOを辿る処理が重い大量更新は小さいトランザクションに分割してコミット

REDOとトランザクションでよくある誤り

REDO/UNDOの仕組みを誤解したまま運用すると、障害時の復旧やパフォーマンス対応を誤る。

誤り何が起きるか正しい対処
REDOログを小さく設定してディスクを節約するログ切替が頻繁に発生し、checkpoint起因のI/O増加とlog file switch待機でパフォーマンスが低下するREDOログは15〜30分に1回程度の切替頻度になるサイズ(通常500MB〜1GB)に設定する
NOLOGGING設定のままバックアップなしで運用する障害時にNOLOGGINGで書き込んだブロックはメディアリカバリで復旧できず、再作成が必要になるNOLOGGING使用後は必ずバックアップを取得するか、本番環境ではLOGGINGモードを維持する
大量更新を1トランザクションで実行するUNDOセグメントが枯渇するとORA-01555が発生し、ロールバックにも時間がかかる大量更新はバッチサイズ(例:10000件単位)に分割してCOMMITし、UNDO使用量を分散させる