Oracle の通常の DML は、障害回復のために変更内容を REDO ログに記録します。NOLOGGING を指定すると、特定の操作において REDO ログへの書き込みを最小限に抑え、大量データのロードや索引の再作成を数倍高速化できます。
ただし NOLOGGING を使った操作後にメディア障害(ディスク障害)が発生すると、NOLOGGING で書き込んだデータは REDO から復元できません。適切なバックアップ戦略と組み合わせて使うことが重要です。
- NOLOGGING でどの操作が高速化されるか(対応操作と非対応操作)
- テーブル・インデックス・パーティションへの NOLOGGING の設定方法
- ダイレクト・パス INSERT(APPEND ヒント)との組み合わせ
- FORCE LOGGING でデータベース全体の NOLOGGING を無効化する方法
- NOLOGGING 使用後のメディア障害リスクと対処法
- ALL_TABLES / ALL_INDEXES の LOGGING 列での設定確認
NOLOGGING の仕組みと REDO ログとの関係
Oracle はすべての変更操作を REDO ログに記録します。これが Instance Recovery(インスタンス障害後の自動回復)の基盤です。NOLOGGING は REDO への書き込みを最小化することで I/O を削減し、ログバッファの競合を緩和します。
| 操作 | NOLOGGING 対応 | 効果 |
|---|---|---|
| CREATE TABLE AS SELECT (CTAS) | 対応 | データブロックの REDO を抑制 |
| CREATE INDEX(全体再作成) | 対応 | インデックスブロックの REDO を抑制 |
| INSERT /*+ APPEND */ (ダイレクト・パス INSERT) | 対応 | データブロックの REDO を抑制 |
| ALTER TABLE MOVE | 対応 | 移動先ブロックの REDO を抑制 |
| ALTER INDEX REBUILD | 対応 | インデックスブロックの REDO を抑制 |
| 通常の INSERT / UPDATE / DELETE | 非対応 | NOLOGGING 設定に関わらず REDO に記録される |
| SELECT | 非対応(無意味) | – |
NOLOGGING でも操作自体のメタデータ(「このブロックは NOLOGGING で更新された」という記録)は REDO に書かれます。完全にログが生成されないわけではなく、ブロックの変更前後の差分(REDO データ)を抑制するものです。
テーブルとインデックスへの NOLOGGING 設定
-- CREATE TABLE に NOLOGGING を付ける
CREATE TABLE sales_archive (
sale_id NUMBER,
sale_date DATE,
amount NUMBER
) NOLOGGING; -- ← テーブル属性として NOLOGGING を設定
-- 既存テーブルを NOLOGGING に変更する
ALTER TABLE sales_archive NOLOGGING;
-- LOGGING に戻す
ALTER TABLE sales_archive LOGGING;
-- CREATE TABLE AS SELECT (CTAS) + NOLOGGING: 非常に速い
CREATE TABLE new_sales NOLOGGING AS
SELECT * FROM sales WHERE sale_date >= DATE '2024-01-01';
-- LOGGING の場合より大幅に REDO 書き込みが減る(ケースによっては数倍高速)
-- CREATE INDEX + NOLOGGING
CREATE INDEX idx_sales_date ON sales(sale_date) NOLOGGING;
-- 既存インデックスを NOLOGGING で再作成する(REBUILD)
ALTER INDEX idx_sales_date REBUILD NOLOGGING;
-- インデックスを REBUILD 後に LOGGING に戻す
ALTER INDEX idx_sales_date LOGGING;
-- パーティション単位での NOLOGGING 設定
CREATE TABLE sales_partitioned (
sale_id NUMBER,
sale_date DATE,
amount NUMBER
)
PARTITION BY RANGE (sale_date) (
PARTITION p2023 VALUES LESS THAN (DATE '2024-01-01') NOLOGGING,
PARTITION p2024 VALUES LESS THAN (DATE '2025-01-01') LOGGING
);
-- アーカイブパーティションは NOLOGGING、最新データは LOGGING と使い分けられる
ダイレクト・パス INSERT(APPEND ヒント)との組み合わせ
テーブルが NOLOGGING の場合でも、通常の INSERT は REDO に記録されます。APPEND(または APPEND_VALUES)ヒントによるダイレクト・パス INSERT を組み合わせることで、INSERT も REDO 最小化の恩恵を受けられます。
-- NOLOGGING テーブルへの通常 INSERT(REDO に記録される)
INSERT INTO sales_archive SELECT * FROM sales_staging;
COMMIT;
-- NOLOGGING 属性があっても、通常 INSERT は REDO が生成される
-- APPEND ヒント + NOLOGGING テーブル: REDO を最小化できる
INSERT /*+ APPEND */ INTO sales_archive
SELECT * FROM sales_staging;
COMMIT;
-- ダイレクト・パス INSERT では NOLOGGING テーブルへの挿入で REDO を抑制できる
-- APPEND で HIGH WATER MARK 以降に書き込む(既存データはスキャン不要)
-- → ただし、COMMIT するまでテーブルはロックされる(他セッションからの INSERT 不可)
-- ダイレクト・パス INSERT + PARALLEL でさらに高速化
INSERT /*+ APPEND PARALLEL(4) */ INTO sales_archive
SELECT * FROM sales_staging;
COMMIT;
-- REDO 生成量を確認する(V$MYSTAT で統計値を比較)
SELECT s.name, ss.value
FROM V$MYSTAT ss, V$STATNAME s
WHERE ss.statistic# = s.statistic#
AND s.name IN ('redo size', 'redo entries')
ORDER BY s.name;
-- REDO サイズがどれだけ減ったか確認できる
FORCE LOGGING でデータベース全体の NOLOGGING を無効化する
FORCE LOGGING はデータベース全体(または PDB)で NOLOGGING を無効化する設定です。Oracle Data Guard(スタンバイへのログ送信)やGoldenGate(CDC ツール)を使っている環境では、NOLOGGING でデータが書き込まれるとスタンバイに反映されないためFORCE LOGGING が必須です。
-- データベースが FORCE LOGGING モードかどうかを確認する SELECT name, force_logging FROM V$DATABASE; -- force_logging = YES: NOLOGGING 指定をすべて無視してフル REDO を生成する -- FORCE LOGGING を有効化する(DBA 権限が必要) ALTER DATABASE FORCE LOGGING; -- FORCE LOGGING を無効化する ALTER DATABASE NO FORCE LOGGING; -- Pluggable Database (PDB) 単位での FORCE LOGGING(Oracle 12c マルチテナント環境) ALTER PLUGGABLE DATABASE FORCE LOGGING; ALTER PLUGGABLE DATABASE NO FORCE LOGGING; -- NOLOGGING ブロックが存在するかどうかを確認する -- NOLOGGING で書き込まれたブロックは V$DATAFILE の UNRECOVERABLE_CHANGE# > 0 になる SELECT file#, name, unrecoverable_change#, unrecoverable_time FROM V$DATAFILE WHERE unrecoverable_change# > 0; -- 0 以外の行がある = このデータファイルに NOLOGGING 書き込みが存在する -- → 障害時に Recovery が必要かどうかの判断に使う
NOLOGGING のリスクとバックアップ戦略
NOLOGGING で書き込んだデータはアーカイブ REDO ログから復元できません。NOLOGGING 操作後にメディア障害が発生した場合、その操作で書き込んだデータは「ORA-26040: Data block was loaded using the NOLOGGING option」エラーが返り、ブロックが復元不可能な状態になります。NOLOGGING 操作が完了したら直ちにバックアップ(RMAN など)を取得してください。
-- 安全な NOLOGGING 運用手順: -- 1. NOLOGGING 操作前にバックアップを確認する -- 2. NOLOGGING 操作を実行する -- 3. 操作後に RMAN バックアップを取得する(完全バックアップ または 増分バックアップ) -- RMAN での NOLOGGING ブロックを含むデータファイルのバックアップ -- RMAN> BACKUP DATAFILE 5, 6; -- NOLOGGING 書き込みがあったデータファイルをバックアップ -- テーブル・インデックスの LOGGING 設定を確認する SELECT table_name, logging FROM USER_TABLES WHERE logging = 'NO' -- NOLOGGING テーブルを一覧する ORDER BY table_name; SELECT index_name, logging FROM USER_INDEXES WHERE logging = 'NO' -- NOLOGGING インデックスを一覧する ORDER BY index_name; -- 本番環境での一般的な使い方: -- ・バッチ処理の中間テーブル(GTT や一時作業テーブル)→ NOLOGGING で問題なし -- ・アーカイブ用の書き込み専用テーブル → バックアップ後は NOLOGGING で高速ロード -- ・Data Guard がある場合 → FORCE LOGGING を設定して NOLOGGING を禁止する -- ・インデックスの定期 REBUILD → NOLOGGING で時間を短縮し、直後にバックアップ
まとめ
- NOLOGGING の効果:CREATE TABLE AS SELECT・CREATE INDEX・ダイレクト・パス INSERT などの「バルク操作」でブロックへの REDO 書き込みを最小化する。通常の INSERT/UPDATE/DELETE は NOLOGGING 設定に関わらず REDO に記録される
- APPEND ヒントとの組み合わせ:NOLOGGING テーブルにダイレクト・パス INSERT することで、大量データの挿入も REDO を抑制できる
- FORCE LOGGING:Data Guard / GoldenGate 環境では必須。ALTER DATABASE FORCE LOGGING でデータベース全体の NOLOGGING を無効化する
- リスク管理:NOLOGGING で書いたデータはアーカイブ REDO から復元不可。操作後は必ず RMAN バックアップを取る
- 設定確認:USER_TABLES.LOGGING / USER_INDEXES.LOGGING で YES/NO を確認する。V$DATAFILE.UNRECOVERABLE_CHANGE# でNOLOGGING ブロックの有無を確認する
REDO ログの管理(サイズ変更・ログスイッチの確認)については オンライン REDO ログ完全ガイドを参照してください。ダイレクト・パス INSERT の詳細は ダイレクト・パス INSERT 完全ガイドも参照してください。