「コミットしたのにデータが消えた」と青ざめた経験がある方は少なくないはずです。REDOログの仕組みを理解しておくと、そうした場面での原因切り分けが格段に早くなります。
ACIDとトランザクション
図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ログ書き込みの流れ
- UPDATE実行: サーバプロセスがバッファキャッシュ上のブロックを変更し、REDOログバッファに「変更ベクトル」を書く。
- COMMIT: セッションが
COMMITを発行。 - LGWR ⇒ ディスク: LGWRがREDOログバッファをオンラインREDOログ(ディスク)にフラッシュする。
- コミット完了応答: ディスク書込み完了をもってクライアントにOKを返す。
- 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使用量を分散させる |