Oracle の REDO ログには、デフォルトでは DML 操作を「やり直す」ために最低限必要な情報だけが記録されます。しかし論理レプリケーション(Oracle GoldenGate・LogMiner・Oracle Streams)では、UPDATE/DELETE の前イメージ(変更前の値)が必要です。
補足ロギング(Supplemental Logging)を有効にすると、REDO ログに変更前の列値など追加情報が記録されるようになります。これにより LogMiner で正確な変更前データを確認したり、GoldenGate が宛先 DB で正確な行を特定したりできるようになります。
- 補足ロギングが必要な理由と有効化しない場合の問題
- データベースレベルの補足ロギング(最小・ALL・主キー・一意キー・外部キー)の違い
- ALTER DATABASE ADD SUPPLEMENTAL LOG DATA でデータベースレベルの設定を変更する方法
- テーブルレベルの補足ロググループを作成する方法
- V$DATABASE と DBA_LOG_GROUPS / DBA_LOG_GROUP_COLUMNS で設定を確認する方法
- REDO ログサイズへの影響と適切な設定の選び方
補足ロギングが必要な理由
Oracle のデフォルトの REDO ログには、DML を再実行するための情報(新しい値)しか記録されません。例えば UPDATE employees SET salary=9000 WHERE employee_id=100 を実行すると、デフォルトでは「employee_id=100 の salary を 9000 にした」という情報だけが記録されます。
論理レプリケーションでは、宛先データベースで「employee_id=100 の行を特定して更新する」ために主キー値(employee_id=100)が変更前データとして必要です。さらに全列の変更前値が必要なケースもあります(宛先での UPDATE WHERE 条件など)。補足ロギングはこのような追加情報を REDO ログに記録します。
| 補足ロギングなし | 補足ロギングあり |
|---|---|
| 変更後の値のみ記録(REDO 用) | 変更前・変更後の値を記録(UNDO 相当の情報も付加) |
| LogMiner: 変更前値が “UNKNOWN” になる場合がある | LogMiner: 変更前値が正確に取得できる |
| GoldenGate: 行を特定できず適用エラーが発生する場合がある | GoldenGate: 主キーで確実に行を特定して適用できる |
| REDO ログサイズへの影響なし | 設定レベルに応じて REDO ログサイズが増加する |
データベースレベルの補足ロギング設定
-- 現在の補足ロギング設定を確認する(SYS / SELECT ANY DICTIONARY 権限が必要)
SELECT
name,
db_unique_name,
supplemental_log_data_min, -- YES/NO: 最小補足ロギング
supplemental_log_data_pk, -- YES/NO: 主キー補足ロギング
supplemental_log_data_ui, -- YES/NO: 一意インデックス補足ロギング
supplemental_log_data_fk, -- YES/NO: 外部キー補足ロギング
supplemental_log_data_all -- YES/NO: 全列補足ロギング
FROM V$DATABASE;
-- 最小補足ロギングを有効にする(LogMiner の最低要件)
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
-- 効果: トランザクション識別に必要な最小限の情報を追加する
-- 主キー補足ロギングを有効にする(GoldenGate の推奨設定)
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
-- 効果: 主キー列の変更前値を全 DML に記録する(UPDATE/DELETE 時に主キー値が確実に記録される)
-- 一意インデックス列の補足ロギングを有効にする
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (UNIQUE INDEX) COLUMNS;
-- 外部キー列の補足ロギングを有効にする
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS;
-- 全列の補足ロギングを有効にする(最大の情報量・REDO ログサイズへの影響が大きい)
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
-- 複数をまとめて有効にする(GoldenGate 標準設定)
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;
-- 補足ロギングを無効にする(段階的に解除する)
ALTER DATABASE DROP SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;
- LogMiner のみ:最小補足ロギング(
SUPPLEMENTAL LOG DATA)で十分 - Oracle GoldenGate:主キー補足ロギング(
PRIMARY KEY)が必須。宛先テーブルに主キーがない場合はALLを検討 - Oracle Streams / 論理スタンバイ:
ALLまたは個別テーブルレベルの設定 - REDO ログサイズの懸念:データベースレベルで
ALLは REDO サイズへの影響が大きい。テーブルレベルで必要なテーブルのみ設定することを検討する
テーブルレベルの補足ロググループ設定
データベース全体ではなく、特定のテーブルのみ補足ロギングを設定したい場合はテーブルレベルの補足ロググループを使います。特定列のみを対象にすることで REDO ログサイズへの影響を最小限に抑えられます。
-- 最小補足ロギングはデータベースレベルで有効にしておく必要がある
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
-- テーブルの全列に補足ロギングを設定する(テーブルレベル ALL)
ALTER TABLE hr.employees ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
-- 主キー列のみ補足ロギングを設定する(テーブルレベル PRIMARY KEY)
ALTER TABLE hr.employees ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
-- 特定列に補足ロググループを作成する(名前付きロググループ)
-- ALWAYS: DML のたびにこのグループの全列を記録する
ALTER TABLE hr.employees ADD SUPPLEMENTAL LOG GROUP emp_suplog_grp (
employee_id,
department_id,
salary
) ALWAYS;
-- ロググループを削除する
ALTER TABLE hr.employees DROP SUPPLEMENTAL LOG GROUP emp_suplog_grp;
-- テーブルレベルの補足ロググループを確認する
SELECT
log_group_name,
table_name,
log_group_type, -- USER LOG GROUP / ALL COLUMN LOGGING など
always -- ALWAYS: 常に記録 / CONDITIONAL: 列変更時のみ
FROM DBA_LOG_GROUPS
WHERE owner = 'HR'
ORDER BY table_name, log_group_name;
-- ロググループに含まれる列を確認する
SELECT
lg.log_group_name,
lgc.column_name,
lgc.position,
lgc.log_group_column_type -- LOG: 記録する / NO LOG: 記録しない
FROM DBA_LOG_GROUPS lg
JOIN DBA_LOG_GROUP_COLUMNS lgc
ON lg.owner = lgc.owner AND lg.log_group_name = lgc.log_group_name
WHERE lg.owner = 'HR'
ORDER BY lg.table_name, lg.log_group_name, lgc.position;
REDO ログサイズへの影響と注意点
補足ロギングを有効にすると、REDO ログに記録される情報量が増えます。一般的な目安として:
- 最小補足ロギング:REDO サイズへの影響はほぼなし
- 主キー補足ロギング:数 % 程度の増加(主キーが小さい場合)
- 全列補足ロギング(ALL):UPDATE/DELETE で列数が多いテーブルでは数十 % 増加することがある
OLTP 環境では特に大量 UPDATE が多いテーブルへの全列補足ロギング適用は慎重に検討してください。
-- 補足ロギング設定前後の REDO 生成量を AWR で比較する
SELECT
begin_interval_time,
end_interval_time,
redo_size_delta / 1024 / 1024 AS redo_mb_delta
FROM (
SELECT
s.begin_interval_time,
s.end_interval_time,
(e.value - b.value) AS redo_size_delta
FROM DBA_HIST_SYSSTAT e
JOIN DBA_HIST_SYSSTAT b
ON e.snap_id = b.snap_id + 1
AND e.instance_number = b.instance_number
AND e.stat_name = b.stat_name
JOIN DBA_HIST_SNAPSHOT s
ON e.snap_id = s.snap_id
AND e.instance_number = s.instance_number
WHERE e.stat_name = 'redo size'
)
ORDER BY begin_interval_time DESC
FETCH FIRST 24 ROWS ONLY;
-- アーカイブログのサイズを確認する(V$ARCHIVED_LOG)
SELECT
TRUNC(first_time, 'HH24') AS hour,
COUNT(*) AS log_count,
SUM(blocks * block_size) / 1024 / 1024 AS total_mb
FROM V$ARCHIVED_LOG
WHERE first_time >= SYSDATE - 7
AND standby_dest = 'NO'
GROUP BY TRUNC(first_time, 'HH24')
ORDER BY hour DESC
FETCH FIRST 48 ROWS ONLY;
まとめ
- 補足ロギングの目的:REDO ログに変更前の列値など追加情報を記録する。LogMiner・Oracle GoldenGate・論理レプリケーションで必要
- 最小補足ロギング:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA。LogMiner の最低要件。REDO サイズへの影響はほぼなし - 主キー補足ロギング:GoldenGate の標準設定。UPDATE/DELETE の行特定に主キー値を確実に記録する
- テーブルレベル設定:
ALTER TABLE ... ADD SUPPLEMENTAL LOG DATAで特定テーブルのみに設定できる。REDO サイズへの影響を最小化できる - V$DATABASE:
supplemental_log_data_min/pk/ui/fk/all列でデータベースレベルの設定を確認する - DBA_LOG_GROUPS:テーブルレベルのロググループを確認する。
DBA_LOG_GROUP_COLUMNSで対象列を確認する - ALL 設定は慎重に:全列補足ロギングは REDO ログサイズを大幅に増加させる可能性がある。UPDATE 頻度の高いテーブルは特に注意
LogMiner を使って変更履歴を確認する方法は LogMiner完全ガイドを参照してください。REDO ログの管理方法と AWR レポートの見方は REDO ログ完全ガイド・AWR/ASH完全ガイドも参照してください。