OracleのREDOログとUNDOの仕組みと管理【障害対応・容量トラブルを解決する】

当ページのリンクには広告が含まれています。

「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を使って変更前に戻す

両者の違いまとめ

REDOUNDO
目的障害復旧(前進)ロールバック・読み取り一貫性
保存場所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.log

3. 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
UNEXPIREDundo_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モードを有効化

関連記事:

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

ITの事や自分の経験談など綴っていきたいと思っています。

コメント

コメントする

CAPTCHA


目次