「REDO」「UNDO」「COMMIT」「ロールバック」——Oracleを扱っていると必ず出てくるこれらのキーワード。仕組みを理解すれば、障害対応・パフォーマンスチューニング・容量管理がぐっと楽になります。
目次
1. REDOとUNDOの仕組みを図解で理解 {#mechanism}
REDOログとは
REDOログは「変更履歴」を記録するファイルです。障害発生時にデータを前進復旧(ロールフォワード)するために使用します。
変更操作
↓
REDOログバッファ(メモリ)に書き込み
↓
COMMIT または バッファが一定量に → REDOログファイル(ディスク)に書き込み
↓
障害発生後の起動時にREDOログを使ってデータを復元REDOログが書き込まれるタイミング:
- COMMIT実行時(必ずディスクに書き込む)
- REDOログバッファが1/3埋まったとき
- DBwriterがデータファイルに書き込む前
- タイムアウト(3秒ごと)
UNDOとは
UNDOは「変更前のデータ」を保存する領域です。ロールバックや読み取り一貫性(他セッションが更新中でも古い値を読める機能)のために使用します。
UPDATE文を実行
├── REDOログ:「どう変更したか」を記録
└── UNDOセグメント:「変更前の値」を記録
COMMIT → UNDOは一定時間保持(undo_retentionで設定)
ROLLBACK → UNDOを使って変更前に戻す両者の違いまとめ
| REDO | UNDO | |
|---|---|---|
| 目的 | 障害復旧(前進) | ロールバック・読み取り一貫性 |
| 保存場所 | REDOログファイル(.log) | UNDO表領域(.dbf) |
| いつ使う | データファイル障害時の復旧 | ROLLBACK / SELECT時の古い値 |
| 典型的なエラー | ORA-03113(接続切断) | ORA-01555(古すぎるスナップショット) |
2. REDOログの確認と管理 {#redo-management}
REDOロググループとメンバーの確認
-- REDOロググループの状態確認
SELECT
l.GROUP#,
l.MEMBERS,
l.BYTES / 1024 / 1024 AS サイズMB,
l.STATUS,
l.ARCHIVED
FROM
V$LOG l
ORDER BY
l.GROUP#;STATUSの意味:
| STATUS | 意味 |
|---|---|
| CURRENT | 現在書き込み中 |
| ACTIVE | まだアーカイブ/チェックポイントが完了していない |
| INACTIVE | 使用済み・再利用可能 |
| UNUSED | まだ一度も使われていない |
REDOログファイルの物理パスを確認
SELECT
l.GROUP#,
lf.MEMBER AS ファイルパス,
l.BYTES / 1024 / 1024 AS サイズMB,
l.STATUS
FROM
V$LOG l
JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP#
ORDER BY
l.GROUP#, lf.MEMBER;REDOロググループを追加する
-- 新しいグループ(グループ4)を追加
ALTER DATABASE ADD LOGFILE GROUP 4
('/u01/oradata/ORCL/redo04a.log',
'/u02/oradata/ORCL/redo04b.log') -- 多重化推奨
SIZE 200M;REDOログのサイズを変更する(削除→追加)
既存のREDOログはサイズ変更できないため、新しいグループを追加して古いグループを削除します。
-- Step1: 新グループを大きいサイズで追加
ALTER DATABASE ADD LOGFILE GROUP 4
'/u01/oradata/ORCL/redo04.log' SIZE 500M;
-- Step2: INACTIVE状態になるまでログスイッチを繰り返す
ALTER SYSTEM SWITCH LOGFILE; -- 何度か実行
-- Step3: INACTIVE になったグループを削除
ALTER DATABASE DROP LOGFILE GROUP 1;
-- Step4: OSからファイルも削除(オプション)
-- rm /u01/oradata/ORCL/redo01.log3. REDOログのパフォーマンス問題と対処 {#redo-performance}
log file sync 待機が多い場合
log file sync はCOMMIT時にREDOログへの書き込み完了を待つ待機イベントです。これが多い場合は:
-- log file sync の発生状況を確認
SELECT EVENT, TOTAL_WAITS, AVERAGE_WAIT
FROM V$SYSTEM_EVENT
WHERE EVENT = 'log file sync'
ORDER BY TOTAL_WAITS DESC;原因と対処:
| 原因 | 対処 |
|---|---|
| COMMIT頻度が高すぎる | バッチ処理のCOMMIT間隔を増やす |
| REDOログファイルが遅いディスクにある | 高速ディスク(SSD等)への移動 |
| REDOログが小さすぎる | ログサイズを大きくする |
ログスイッチが頻繁に起きている
-- 1時間あたりのログスイッチ回数を確認
SELECT
TO_CHAR(FIRST_TIME, 'YYYY-MM-DD HH24') AS 時間帯,
COUNT(*) AS スイッチ回数
FROM
V$LOG_HISTORY
WHERE
FIRST_TIME >= SYSDATE - 1
GROUP BY
TO_CHAR(FIRST_TIME, 'YYYY-MM-DD HH24')
ORDER BY
時間帯;💡 1時間に4回以上スイッチが発生する場合、REDOログが小さすぎる可能性があります。ログサイズを大きくすることを検討してください。
4. UNDO表領域の確認と管理 {#undo-management}
UNDO設定の確認
-- UNDO関連パラメータの確認
SHOW PARAMETER undo_tablespace; -- 使用中のUNDO TBS
SHOW PARAMETER undo_retention; -- 保持時間(秒)
SHOW PARAMETER undo_management; -- AUTO が推奨UNDO使用状況の確認
-- UNDOセグメントのステータス別容量
SELECT
STATUS,
SUM(BYTES) / 1024 / 1024 AS 合計MB,
COUNT(*) AS セグメント数
FROM
DBA_UNDO_EXTENTS
GROUP BY
STATUS;STATUS の意味:
| STATUS | 意味 |
|---|---|
| ACTIVE | 現在使用中のトランザクションが持つUNDO |
| UNEXPIRED | undo_retention期間内(まだ使われる可能性がある) |
| EXPIRED | 再利用可能(解放された) |
UNDOの必要サイズを計算する
-- 直近のUNDO生成量(1秒あたりのUNDOブロック数)
SELECT
ROUND(UNDOBLKS / ((END_TIME - BEGIN_TIME) * 86400), 1) AS UNDOブロック/秒,
ROUND(UNDOBLKS * 8192 / 1024 / 1024 / ((END_TIME - BEGIN_TIME) * 86400 / 3600), 1) AS UNDO MB/時間
FROM
V$UNDOSTAT
WHERE
ROWNUM = 1;5. アーカイブログモードの確認と切り替え {#archive-mode}
アーカイブログモードの確認
-- アーカイブログモードの確認
ARCHIVE LOG LIST;
-- または
SELECT LOG_MODE FROM V$DATABASE;出力例:
Database log mode Archive Mode ← 本番推奨
Automatic archival Enabled
Archive destination /u01/archive
Oldest online log sequence 230
Next log sequence to archive 232
Current log sequence 232アーカイブログモードへの切り替え
-- Step1: データベースをSHUTDOWN
SHUTDOWN IMMEDIATE;
-- Step2: MOUNTモードで起動
STARTUP MOUNT;
-- Step3: アーカイブログモードに変更
ALTER DATABASE ARCHIVELOG;
-- Step4: データベースをOPEN
ALTER DATABASE OPEN;
-- Step5: 確認
ARCHIVE LOG LIST;⚠️ 本番では必ずアーカイブログモードを有効化してください。 NOARCHIVELOGモードではメディア障害からの完全復旧ができません。
アーカイブログの場所と容量を確認する
-- アーカイブログの保存先を確認
SHOW PARAMETER log_archive_dest;
-- アーカイブログの容量(DB_RECOVERY_FILE_DEST使用時)
SELECT
SPACE_LIMIT / 1024 / 1024 / 1024 AS 上限GB,
SPACE_USED / 1024 / 1024 / 1024 AS 使用GB,
ROUND(SPACE_USED / SPACE_LIMIT * 100, 1) AS 使用率
FROM
V$RECOVERY_FILE_DEST;6. よくあるトラブルと対処法 {#troubles}
ORA-00257: アーカイバーエラー
原因: アーカイブログの保存先がディスク満杯で書き込めない。
# アーカイブログを古いものから削除(RMANで管理している場合)
rman target /
RMAN> DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';
RMAN> EXIT;-- DB_RECOVERY_FILE_DESTの容量を確認
SELECT SPACE_LIMIT/1024/1024/1024 AS 上限GB, SPACE_USED/1024/1024/1024 AS 使用GB
FROM V$RECOVERY_FILE_DEST;
-- 上限を増やす(根本対処)
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 100G SCOPE = BOTH;ORA-01555: スナップショットが古すぎます
原因: 実行中のSELECTが必要なUNDOデータが上書きされた。
-- Step1: 問題のSQLの実行時間を確認して必要なUNDO保持時間を計算
-- Step2: undo_retentionを延長(秒単位)
ALTER SYSTEM SET UNDO_RETENTION = 3600 SCOPE = BOTH; -- 1時間
-- Step3: UNDO TBSにGUARANTEEを設定(容量があれば保持を保証)
ALTER TABLESPACE UNDOTBS1 RETENTION GUARANTEE;
-- Step4: UNDO TBSのサイズが十分かを確認して足りなければ拡張7. まとめ:REDO/UNDO管理チェックリスト {#summary}
REDOログ管理:
| チェック項目 | 確認SQL/コマンド |
|---|---|
| REDOロググループ数・サイズ確認 | V$LOG |
| REDOログファイルパス確認 | V$LOGFILE |
| ログスイッチ頻度確認 | V$LOG_HISTORY |
| log file sync 待機確認 | V$SYSTEM_EVENT |
| アーカイブログモード確認 | ARCHIVE LOG LIST |
| アーカイブログ容量確認 | V$RECOVERY_FILE_DEST |
UNDO管理:
| チェック項目 | 確認SQL/コマンド |
|---|---|
| UNDO設定確認 | SHOW PARAMETER undo_* |
| UNDO使用状況確認 | DBA_UNDO_EXTENTS |
| UNDO TBS残量確認 | DBA_FREE_SPACE |
| ORA-01555対策 | undo_retention パラメータ延長 |
推奨設定(本番環境):
- REDOログ: 3グループ以上、各グループ多重化(別ディスク)、サイズ200MB〜1GB
- UNDO: undo_retentionは最長トランザクション時間の2倍以上
- アーカイブログ: 必ずARCHIVELOGモードを有効化
関連記事:









コメント