Oracleメモリー構造の基本とパフォーマンスを最大化するチューニング戦略

Oracle Master Gold

Oracle Databaseのパフォーマンスを考えるうえで、メモリー設計は非常に重要です。

適切なメモリーが割り当てられていれば、データファイルへの物理I/O、SQLのハードパース、ソートやハッシュ結合に伴う一時表領域へのI/Oを削減できます。

一方で、メモリーを増やせば必ず高速化するわけではありません。

たとえば、物理I/Oの増加はバッファキャッシュ不足だけでなく、非効率なSQL、索引不足、大規模な全表走査、ワークロードの変化などでも発生します。共有プールのハードパースも、共有プール不足だけでなく、リテラルSQLの大量発行、オブジェクトの変更、実行環境の違いなどが原因になることがあります。

したがって、Oracle Databaseのメモリーチューニングでは、次の順序を守ることが重要です。

症状を確認
   ↓
待機イベント・統計情報・アドバイザを確認
   ↓
原因がメモリー不足かを判断
   ↓
SGAまたはPGAを変更
   ↓
変更前後の性能を比較

本記事では、Oracle Database 19cを対象として、SGAとPGAの違い、主要なメモリーコンポーネント、自動メモリー管理、確認用SQL、代表的なトラブルへの対処方法を解説します。

Statspackとは?SEでも使えるOracle性能診断ツールの基本と活用法
Oracleのパフォーマンス分析というと「AWR(Automatic Workload Repository)」が思い浮かぶかもしれませんが、AWRはEnterprise Edition(EE)限定で、Diagnostic Packのライセ…
AWR(Automatic Workload Repository)とは?Oracle性能分析の基礎から実践まで解説!
Oracle Databaseの運用中、「システムのレスポンスが急に遅くなった」「CPU使用率が高止まりしている」といったパフォーマンス問題に直面したことはありませんか?そんな時に最も頼りになる公式ツールが AWR(Automatic Wo…

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


  1. Oracle Databaseのメモリー構造
    1. メモリー構造の全体図
  2. 1. データベース・バッファ・キャッシュ
    1. バッファキャッシュ不足を疑う症状
  3. 2. 共有プール
    1. ハードパースが増える主な原因
  4. 3. REDOログ・バッファ
  5. 4. ラージ・プール
  6. 5. Javaプール
  7. 6. In-Memory領域
  8. PGA_AGGREGATE_TARGETは上限ではない
  9. AMM:自動メモリー管理
    1. AMMのメリット
    2. AMMの注意点
  10. ASMM:自動共有メモリー管理
    1. ASMMのメリット
    2. ASMMの注意点
  11. Linux環境ではどちらを選ぶべきか
  12. 実行権限とCDB環境での注意点
  13. 1. SGA全体の概要を確認する
  14. 2. メモリー関連パラメータを確認する
    1. AMMの代表的な状態
    2. ASMMの代表的な状態
  15. 3. SGAコンポーネントの現在サイズを確認する
  16. 4. SGAのサイズ変更履歴を確認する
  17. 5. バッファキャッシュの拡張効果を確認する
  18. 6. 共有プールのアドバイス情報を確認する
  19. 7. ハードパースの発生状況を確認する
  20. 8. PGAの使用状況を確認する
  21. 9. Optimal、One-pass、Multi-passの回数を確認する
  22. 10. PGA_AGGREGATE_TARGETの変更効果を確認する
  23. 11. PGAを多く使用しているプロセスを確認する
  24. 手順1:変更前の値を記録する
  25. 手順2:OS側のメモリーを確認する
  26. 手順3:Oracleのアドバイザを確認する
  27. 手順4:一度に複数のパラメータを変更しない
  28. 手順5:変更後の差分を確認する
  29. 手順6:改善しなければ元に戻す
  30. エラーメッセージ
  31. 主な原因
  32. 確認例
  33. 対処方針
    1. ALTER SYSTEM FLUSH SHARED_POOLについて
  34. エラーメッセージ
  35. 主な原因
  36. 注意点
  37. エラーメッセージ
  38. Q1. バッファキャッシュは大きいほど高速になりますか
  39. Q2. ASMMではDB_CACHE_SIZEやSHARED_POOL_SIZEを0にすべきですか
  40. Q3. PGA_AGGREGATE_TARGETを超えることはありますか
  41. Q4. TEMP表領域を使用していればPGA不足ですか
  42. Q5. ORA-04031が発生したら共有プールをフラッシュすればよいですか

Oracle Databaseのメモリー構造

Oracle Databaseインスタンスが使用する主要なメモリー領域は、次の2つです。

  • SGA:複数のOracleプロセスで共有するメモリー
  • PGA:Oracleプロセスごとに使用するプライベートメモリー

Oracle Databaseでは、SGAと各プロセスのPGAを組み合わせてSQLを処理します。SGAはインスタンス起動時に確保されますが、AMMまたはASMMを使用している場合、一部のコンポーネントは稼働中に動的に拡大・縮小されます。PGAはサーバープロセスやバックグラウンドプロセスごとに確保されます。

メモリー構造の全体図

+------------------------------------------------------------------+
|                       Oracle Databaseインスタンス                 |
+------------------------------------------------------------------+
|                                                                  |
|  +--------------------------- SGA -----------------------------+  |
|  | 複数のOracleプロセスで共有                                  |  |
|  |                                                              |  |
|  |  ・データベース・バッファ・キャッシュ                       |  |
|  |  ・共有プール                                                 |  |
|  |  ・REDOログ・バッファ                                         |  |
|  |  ・ラージ・プール                                             |  |
|  |  ・Javaプール                                                  |  |
|  |  ・Streamsプール                                               |  |
|  |  ・In-Memory領域など                                          |  |
|  +--------------------------------------------------------------+  |
|                                                                  |
|  +--------- PGA ---------+  +--------- PGA ---------+             |
|  | サーバープロセス1用   |  | サーバープロセス2用   |   ……        |
|  |                       |  |                       |             |
|  | ・ソート作業領域      |  | ・ソート作業領域      |             |
|  | ・ハッシュ作業領域    |  | ・ハッシュ作業領域    |             |
|  | ・カーソル実行情報    |  | ・カーソル実行情報    |             |
|  +-----------------------+  +-----------------------+             |
|                                                                  |
+------------------------------------------------------------------+
メモリー領域主な用途共有範囲
SGAデータブロック、SQL、実行計画、データディクショナリ情報、REDOなどの保持インスタンス内のOracleプロセスで共有
PGAソート、ハッシュ結合、カーソル実行状態、プロセス固有情報の保持原則としてOracleプロセス単位

専用サーバー構成では、サーバープロセスとユーザーセッションがおおむね1対1で対応します。一方、共有サーバー構成では、セッション状態を保持するUGAの一部または全部がSGA側に配置されるため、「PGAは常にセッション単位」と考えるのは正確ではありません。PGAは、基本的にはプロセス単位のプライベートメモリーです。


SGAの主要コンポーネント

SGAは、用途の異なる複数のメモリーコンポーネントで構成されています。

+------------------------------------------------------------------+
|                              SGA                                 |
+------------------------------------------------------------------+
| データベース・バッファ・キャッシュ                               |
|  └ データファイルから読み込んだデータブロックを保持              |
+------------------------------------------------------------------+
| 共有プール                                                        |
|  ├ ライブラリ・キャッシュ:SQL、PL/SQL、実行計画                 |
|  └ データディクショナリ・キャッシュ:表や列などの定義情報        |
+------------------------------------------------------------------+
| REDOログ・バッファ                                                |
|  └ オンラインREDOログへ書き込む前のREDOエントリを保持            |
+------------------------------------------------------------------+
| ラージ・プール、Javaプール、Streamsプール、In-Memory領域など      |
+------------------------------------------------------------------+
| 固定SGA                                                           |
|  └ インスタンス内部の管理情報                                    |
+------------------------------------------------------------------+

Oracle公式マニュアルでは、バッファキャッシュ、共有プール、REDOログ・バッファ、ラージ・プール、Javaプール、In-Memory領域などが主要なSGAコンポーネントとして説明されています。

1. データベース・バッファ・キャッシュ

データベース・バッファ・キャッシュは、データファイルから読み込んだデータブロックのコピーを保持する領域です。

SQLが必要とするブロックがバッファキャッシュに存在すれば、データファイルから改めて読み込む必要がありません。そのため、適切なサイズのバッファキャッシュは、物理I/Oの削減に大きく貢献します。

ただし、物理読取りが多いという理由だけで、すぐにDB_CACHE_SIZESGA_TARGETを増やすべきではありません。

物理読取りが多くなる原因には、次のようなものがあります。

  • バッファキャッシュが小さい
  • 全表走査を繰り返すSQLがある
  • 必要な索引が存在しない
  • 読み込むデータ量そのものが増加した
  • バッチ処理とオンライン処理が同じ時間帯に集中している
  • SQLの実行計画が変化した

バッファキャッシュを増やす前に、V$DB_CACHE_ADVICEの予測値や、負荷の高いSQL、待機イベントを確認します。V$DB_CACHE_ADVICEでは、キャッシュサイズを変更した場合の推定物理読取り回数を確認できます。

バッファキャッシュ不足を疑う症状

・db file sequential readなどの物理I/O待機が多い
・同じデータブロックが繰り返しデータファイルから読み込まれている
・DB Cache Adviceでキャッシュ拡張による物理読取り削減が予測される

キャッシュ・ヒット率だけで判断せず、「バッファキャッシュを増やした場合に、実際の処理時間や物理読取りがどれだけ減るか」を確認することが重要です。


2. 共有プール

共有プールには、主に次の領域が含まれます。

  • ライブラリ・キャッシュ
  • データディクショナリ・キャッシュ
  • サーバー結果キャッシュなど

ライブラリ・キャッシュには、解析済みSQL、PL/SQLコード、実行計画などが保持されます。同一のSQLを共有できれば、Oracle Databaseは毎回ハードパースを実行する必要がなくなり、CPU、メモリー、ラッチなどの使用量を削減できます。

ハードパースが増える主な原因

共有プールが小さいことだけが原因とは限りません。

ハードパース増加
   ├─ 共有プールが小さく、SQLがキャッシュから追い出される
   ├─ リテラル値だけが異なるSQLが大量に発行される
   ├─ SQL文字列、空白、大文字・小文字などが異なる
   ├─ 参照先スキーマやセッション環境が異なる
   ├─ DDLや統計情報更新などでカーソルが無効化される
   └─ アプリケーションがカーソルを再利用していない

特にOLTPシステムでは、次のようにリテラル値を直接指定したSQLを大量に発行すると、異なるSQLとして処理されやすくなります。

SELECT employee_name
FROM employees
WHERE employee_id = 100;

SELECT employee_name
FROM employees
WHERE employee_id = 101;

バインド変数を使用すると、SQLを共有しやすくなります。

SELECT employee_name
FROM employees
WHERE employee_id = :employee_id;

Oracle公式マニュアルでも、共有カーソルを利用するため、可能な場合はリテラルではなくバインド変数を使用することが推奨されています。ただし、データ分布に大きな偏りがある分析系SQLでは、リテラル値を使用した方が適切な選択性を見積もれるケースもあります。そのため、すべてのSQLを機械的にバインド変数化するのではなく、ワークロードの特性を考慮します。


3. REDOログ・バッファ

REDOログ・バッファは、データベースに対する変更内容を表すREDOエントリを、オンラインREDOログファイルへ書き込む前に保持する循環バッファです。

LGWRプロセスは、REDOログ・バッファの内容をオンラインREDOログファイルへ書き込みます。

大量更新処理などでREDO生成量が多く、LGWRの書込みが追い付かない場合には、log buffer space待機が発生することがあります。

ただし、log buffer spaceが発生したからといって、必ずLOG_BUFFERを大きくすれば解決するわけではありません。

確認すべき項目は次のとおりです。

  • REDOログの格納先ストレージが遅くないか
  • LGWRのI/O待機が増えていないか
  • 短時間に大量のREDOが生成されていないか
  • オンラインREDOログの切替えが過剰に発生していないか
  • redo buffer allocation retriesが増加していないか

LOG_BUFFERは動的に変更できない初期化パラメータであり、デフォルト値はSGAサイズやCPU数などに基づいて決定されます。また、REDOログ・バッファはASMMによる自動サイズ変更の対象外です。


4. ラージ・プール

ラージ・プールは、共有プールから大きな連続メモリーを確保することによる断片化を避けるための任意の領域です。

主に次の処理で使用されます。

  • 共有サーバー構成のセッションメモリー
  • パラレル実行のメッセージバッファ
  • RMANのI/Oバッファ
  • 一部の大きなメモリー割当て

ASMMを使用している場合、ラージ・プールはSGA_TARGETの範囲内で自動調整されます。LARGE_POOL_SIZEに0より大きい値を設定した場合、その値はASMMにおける下限値として扱われます。


5. Javaプール

Javaプールは、Oracle Database内のJava Virtual MachineでJavaコードを実行するために使用されます。

Javaストアドプロシージャなど、データベース内Java機能を使用していない環境では、Javaプールの重要度は比較的低くなります。ASMM環境でJAVA_POOL_SIZEを指定した場合、その値は自動調整時の下限値になります。


6. In-Memory領域

In-Memory領域は、Oracle Database In-Memoryで使用する列指向のデータを保持するSGA領域です。

通常のバッファキャッシュには行形式のデータが保持されますが、In-Memory Column Storeでは分析処理に適した列形式でもデータを保持します。

データファイル
    │
    ├─ バッファキャッシュ:行形式
    │
    └─ In-Memory領域     :列形式

Oracle Database 19cのライセンス体系では、完全なOracle Database In-MemoryはEnterprise Edition向けの有償オプションです。

一方、Enterprise Editionでは、一定の制限付きでIn-Memory機能を試せる「Database In-Memory Base Level」が用意されています。Base Levelでは、In-Memory領域がCDB当たり最大16GBに制限されるなどの条件があります。Standard Edition 2では、Database In-Memory Base Levelを利用できません。ライセンス条件は更新される可能性があるため、導入時点のOracle Database Licensing Information User Manualを必ず確認してください。


PGAの構造と役割

PGAは、サーバープロセスやバックグラウンドプロセスが使用するプライベートメモリーです。

+----------------------------------------------------------+
|                         PGA                              |
+----------------------------------------------------------+
| プライベートSQL領域                                      |
|  ├ カーソル実行状態                                      |
|  ├ バインド変数                                          |
|  └ SQL実行時の制御情報                                   |
+----------------------------------------------------------+
| SQLワークエリア                                          |
|  ├ ソート処理                                            |
|  ├ ハッシュ結合                                          |
|  ├ ビットマップ処理                                      |
|  └ その他のメモリー集中型SQL演算子                      |
+----------------------------------------------------------+
| プロセス固有の管理情報                                   |
+----------------------------------------------------------+

PGAのSQLワークエリアは、次のような処理で使用されます。

  • ORDER BYによるソート
  • GROUP BYによる集計
  • ハッシュ結合
  • ビットマップ処理
  • ウィンドウ関数や分析処理
  • 一部の索引作成処理

Oracle Databaseでは、ワークエリアの実行状態を次の3種類に分類します。

実行モード状態
Optimal必要な作業を主にメモリー内で処理できる
One-passワークエリアが最適サイズより小さく、入力データに対して追加のパスが1回必要
Multi-passワークエリアがさらに小さく、複数回の追加パスが必要

One-passは完全なメモリー内処理ではありません。Optimalより少ないメモリーで処理するため、追加の読取り・書込みが発生し、応答時間が長くなります。Multi-passはさらに大きな性能低下を招くため、可能な限り回避すべきです。

PGAが十分
   └─ Optimal
        └─ 少ない追加I/Oで処理

PGAが不足
   ├─ One-pass
   │    └─ 一時表領域を使用した追加処理
   │
   └─ Multi-pass
        └─ 複数回の追加処理が発生し、大幅に遅延

PGA_AGGREGATE_TARGETは上限ではない

PGA_AGGREGATE_TARGETは、インスタンス全体で使用するPGAの目標値です。

ただし、これは絶対的な上限ではありません。

PGA_AGGREGATE_TARGETで主に制御されるのは、ソートやハッシュ結合などの調整可能なワークエリアです。PL/SQL、Java、その他の調整不能なPGAメモリーが増加した場合、実際のPGA使用量がPGA_AGGREGATE_TARGETを超えることがあります。

絶対的な上限を設定するパラメータが、PGA_AGGREGATE_LIMITです。

PGA_AGGREGATE_LIMITを超過すると、Oracle Databaseは、調整不能なPGAを多く使用しているセッションのコールを中断します。それでも使用量が減らない場合は、対象セッションを終了します。


AMMとASMMの違い

Oracle Databaseには、SGAとPGAを管理する複数の方式があります。

AMM:自動メモリー管理

AMMでは、次のパラメータを使用します。

MEMORY_TARGET
MEMORY_MAX_TARGET

MEMORY_TARGETでSGAとインスタンスPGAの合計目標値を設定すると、Oracle DatabaseがSGAとPGAの間でメモリーを動的に再配分します。

+--------------------- MEMORY_TARGET ----------------------+
|                                                         |
|       SGA                    インスタンスPGA             |
|  +-------------+          +------------------+           |
|  |             | ←調整→   |                  |           |
|  +-------------+          +------------------+           |
|                                                         |
+---------------------------------------------------------+

AMMのメリット

  • SGAとPGAをまとめて管理できる
  • ワークロードに応じてSGAとPGAの配分が変化する
  • 小規模環境や検証環境で管理しやすい

AMMの注意点

Linuxでは、AMMとHugePagesを併用できません。AMMを使用すると、SGAは主に/dev/shmを使用して確保され、HugePagesには割り当てられません。


ASMM:自動共有メモリー管理

ASMMでは、SGAとPGAを分けて設定します。

SGA_TARGET
SGA_MAX_SIZE

PGA_AGGREGATE_TARGET
PGA_AGGREGATE_LIMIT

SGA_TARGETでSGA全体のサイズを指定すると、Oracle Databaseがバッファキャッシュ、共有プール、ラージ・プール、Javaプールなどのサイズを自動調整します。

PGAは、PGA_AGGREGATE_TARGETを使用して別に管理します。

+------------------- SGA_TARGET --------------------+
| バッファキャッシュ ←→ 共有プール ←→ その他      |
+---------------------------------------------------+

+-------------- PGA_AGGREGATE_TARGET ---------------+
| 各OracleプロセスのPGAに対する目標値               |
+---------------------------------------------------+

ASMMのメリット

  • SGAとPGAの配分をDBAが明示的に設計できる
  • SGA内の主要コンポーネントは自動調整される
  • Linux環境でHugePagesを利用できる
  • SGAとPGAのどちらが増えたかを把握しやすい

ASMMの注意点

  • SGAとPGAの間では、AMMのような自動的な融通は行われない
  • ワークロードに応じて、SGAとPGAの配分をDBAが評価する必要がある
  • SGAを増やしすぎると、PGAやOS用メモリーを圧迫する

Linux環境ではどちらを選ぶべきか

Linuxで大きなSGAを使用し、HugePagesを利用する場合は、AMMではなくASMMを選択します。

ただし、「Linuxなら必ずASMM」「HugePagesはすべての環境で必須」と一律に考えるべきではありません。

次の条件を基に判断します。

条件検討する方式
小規模な検証環境AMMまたはASMM
Windows環境AMMも選択肢
LinuxでHugePagesを使用ASMM
大規模な本番環境ASMMを中心に検討
SGAとPGAを明示的に管理したいASMM

OracleのLinux向けマニュアルでは、HugePagesを使用する場合にAMMを無効化する必要があると説明されています。また、HugePagesだけで物理メモリーを使い切らず、通常ページ用のメモリーを確保する必要があります。


ASMM使用時の個別パラメータ

ASMMでは、次の主要コンポーネントがSGA_TARGETの範囲内で自動調整されます。

  • DB_CACHE_SIZE
  • SHARED_POOL_SIZE
  • LARGE_POOL_SIZE
  • JAVA_POOL_SIZE
  • STREAMS_POOL_SIZE

個別パラメータに0より大きい値を設定すると、原則として固定値ではなく、自動調整時の下限値として使用されます。

たとえば、次の設定の場合を考えます。

SGA_TARGET       = 16G
DB_CACHE_SIZE    = 8G
SHARED_POOL_SIZE = 2G

この場合、ASMMはおおむね次の制約で動作します。

SGA全体       :16GB
バッファキャッシュ:最低8GB
共有プール        :最低2GB
残り              :ワークロードに応じて自動配分

個別パラメータを過剰に大きく設定すると、Oracle Databaseが自動調整できる範囲が狭くなります。

明確な最低保証値が必要な場合を除き、個別コンポーネントの下限を必要以上に設定しないことが重要です。


メモリー不足時の症状と確認ポイント

症状疑う領域最初に確認する項目
物理読取りが多いバッファキャッシュSQL、待機イベント、V$DB_CACHE_ADVICE
ハードパースが多い共有プールまたはアプリケーションバインド変数、parse count (hard)、カーソル共有不可理由
TEMPへのI/Oが多いPGAOne-pass、Multi-pass、V$PGA_TARGET_ADVICE
log buffer spaceが多いREDOログ・バッファまたはLGWR I/OREDO生成量、LGWR待機、ストレージ性能
ORA-04031SGA内の対象プールエラーメッセージのヒープ名、トレース、メモリー設定
ORA-04030プロセスのプライベートメモリーOSメモリー、プロセスPGA、OS制限
ORA-04036PGA上限超過PGA_AGGREGATE_LIMIT、大量消費セッション

実践:メモリー確認用SQL

実行権限とCDB環境での注意点

動的パフォーマンスビューを参照するには、通常、次のいずれかの権限が必要です。

  • SYSDBA
  • SELECT_CATALOG_ROLE
  • 必要なV_$ビューに対する個別のSELECT権限
  • SELECT ANY DICTIONARY

本番環境では、必要以上に強い権限を付与せず、参照に必要な権限のみを付与することを推奨します。

SGAとインスタンスPGAはインスタンス単位の情報です。CDB環境でインスタンス全体を確認する場合は、基本的にCDB$ROOTへ接続して実行します。PDB単位のメモリー制限を確認する場合は、CON_IDやPDB側の初期化パラメータも確認してください。V$PGASTATなどの累積値はインスタンス起動時から蓄積されます。


1. SGA全体の概要を確認する

SHOW SGA;

SQL*PlusのSHOW SGAコマンドでは、SGAの概要を次のような区分で確認できます。

Total System Global Area
Fixed Size
Variable Size
Database Buffers
Redo Buffers

これはSQL文ではなく、SQL*Plusのコマンドです。


2. メモリー関連パラメータを確認する

SELECT
    name,
    display_value,
    isdefault,
    issys_modifiable
FROM
    v$parameter
WHERE
    name IN (
        'memory_target',
        'memory_max_target',
        'sga_target',
        'sga_max_size',
        'db_cache_size',
        'shared_pool_size',
        'large_pool_size',
        'java_pool_size',
        'streams_pool_size',
        'log_buffer',
        'pga_aggregate_target',
        'pga_aggregate_limit'
    )
ORDER BY
    name;

このSQLで、AMMとASMMのどちらが使用されているかを判断できます。

AMMの代表的な状態

MEMORY_TARGET > 0

ASMMの代表的な状態

MEMORY_TARGET       = 0
SGA_TARGET          > 0
PGA_AGGREGATE_TARGET > 0

3. SGAコンポーネントの現在サイズを確認する

SELECT
    component,
    ROUND(current_size / 1024 / 1024, 2) AS current_mb,
    ROUND(min_size     / 1024 / 1024, 2) AS min_mb,
    ROUND(max_size     / 1024 / 1024, 2) AS max_mb,
    ROUND(user_specified_size / 1024 / 1024, 2)
        AS user_specified_mb
FROM
    v$sga_dynamic_components
WHERE
    current_size > 0
ORDER BY
    current_size DESC;

V$SGA_DYNAMIC_COMPONENTSでは、動的SGAコンポーネントの現在サイズや、インスタンス起動後に記録された最小・最大サイズを確認できます。


4. SGAのサイズ変更履歴を確認する

SELECT
    component,
    oper_type,
    oper_mode,
    ROUND(initial_size / 1024 / 1024, 2) AS initial_mb,
    ROUND(target_size  / 1024 / 1024, 2) AS target_mb,
    ROUND(final_size   / 1024 / 1024, 2) AS final_mb,
    status,
    start_time,
    end_time
FROM
    v$sga_resize_ops
ORDER BY
    start_time DESC
FETCH FIRST 20 ROWS ONLY;

自動メモリー管理によって、どのコンポーネントが拡大・縮小されたかを確認できます。

頻繁に拡大と縮小を繰り返している場合は、SGA全体が不足しているか、個別コンポーネントに設定した下限値が自動調整を妨げていないかを確認します。


5. バッファキャッシュの拡張効果を確認する

SELECT
    size_for_estimate AS cache_size_mb,
    size_factor,
    estd_physical_reads,
    estd_physical_read_factor,
    estd_physical_read_time
FROM
    v$db_cache_advice
WHERE
    name = 'DEFAULT'
AND block_size = (
        SELECT TO_NUMBER(value)
        FROM v$parameter
        WHERE name = 'db_block_size'
    )
ORDER BY
    size_for_estimate;

主に確認する列は次のとおりです。

内容
CACHE_SIZE_MB評価対象となるキャッシュサイズ
SIZE_FACTOR現在サイズに対する倍率
ESTD_PHYSICAL_READS推定物理読取り数
ESTD_PHYSICAL_READ_FACTOR現在に対する推定物理読取り倍率
ESTD_PHYSICAL_READ_TIME推定物理読取り時間

バッファキャッシュを増やしても推定物理読取り数がほとんど減らない場合、キャッシュ拡張による効果は限定的と考えられます。


6. 共有プールのアドバイス情報を確認する

SELECT
    shared_pool_size_for_estimate AS shared_pool_mb,
    shared_pool_size_factor,
    estd_lc_size,
    estd_lc_memory_objects,
    estd_lc_time_saved,
    estd_lc_time_saved_factor
FROM
    v$shared_pool_advice
ORDER BY
    shared_pool_size_for_estimate;

V$SHARED_POOL_ADVICEでは、共有プールのサイズを変更した場合に、ライブラリ・キャッシュによって節約される推定解析時間などを確認できます。


7. ハードパースの発生状況を確認する

SELECT
    name,
    value
FROM
    v$sysstat
WHERE
    name IN (
        'parse count (total)',
        'parse count (hard)',
        'execute count',
        'session cursor cache hits'
    )
ORDER BY
    name;

parse count (hard)が多い場合は、共有プールのサイズだけでなく、アプリケーションがバインド変数やカーソルキャッシュを使用しているかも確認します。

同一に見えるSQLが共有されない理由は、V$SQL_SHARED_CURSORなどで調査できます。Oracle公式マニュアルでも、共有されないSQLの理由を確認するためにこのビューを使用する方法が案内されています。


8. PGAの使用状況を確認する

SELECT
    name,
    CASE
        WHEN unit = 'bytes'
            THEN ROUND(value / 1024 / 1024, 2)
        ELSE value
    END AS value,
    CASE
        WHEN unit = 'bytes'
            THEN 'MB'
        ELSE unit
    END AS unit
FROM
    v$pgastat
WHERE
    name IN (
        'aggregate PGA target parameter',
        'aggregate PGA auto target',
        'total PGA allocated',
        'total PGA inuse',
        'maximum PGA allocated',
        'total freeable PGA memory',
        'over allocation count',
        'global memory bound',
        'cache hit percentage',
        'extra bytes read/written'
    )
ORDER BY
    name;

元記事にあるcurrent PGA allocatedという統計名は、Oracle Database 19cのV$PGASTATでは使用しません。現在の割当量はtotal PGA allocatedで確認します。

特に重要な統計は次のとおりです。

統計名確認内容
total PGA allocated現在割り当てられているPGA
maximum PGA allocated起動後の最大PGA割当量
aggregate PGA auto target自動ワークエリアに使用可能なPGA
over allocation countPGA目標値を守れず追加割当てした回数
global memory bound個々のワークエリアに割り当てられる最大サイズ
extra bytes read/writtenOptimalで処理できず追加処理されたデータ量

over allocation countが増加している場合は、PGA_AGGREGATE_TARGETが不足している可能性があります。ただし、値は起動後の累積値なので、1回の取得だけでなく、一定時間ごとの差分を確認してください。


9. Optimal、One-pass、Multi-passの回数を確認する

SELECT
    name,
    value
FROM
    v$sysstat
WHERE
    name IN (
        'workarea executions - optimal',
        'workarea executions - onepass',
        'workarea executions - multipass'
    )
ORDER BY
    name;

Multi-passが発生している場合は、PGA不足によって大きな性能低下が発生している可能性があります。

ただし、これらの値もインスタンス起動後の累積値です。問題が発生した時間帯の差分や、対象SQLのV$SQL_WORKAREAを確認する必要があります。


10. PGA_AGGREGATE_TARGETの変更効果を確認する

SELECT
    ROUND(pga_target_for_estimate / 1024 / 1024)
        AS target_mb,
    pga_target_factor,
    estd_pga_cache_hit_percentage,
    estd_overalloc_count,
    ROUND(estd_extra_bytes_rw / 1024 / 1024)
        AS estd_extra_rw_mb
FROM
    v$pga_target_advice
ORDER BY
    pga_target_for_estimate;

V$PGA_TARGET_ADVICEでは、PGA_AGGREGATE_TARGETを変更した場合の次の値を予測できます。

  • PGAキャッシュ・ヒット率
  • 過剰割当て回数
  • 追加の読取り・書込み量
  • 推定処理時間

ESTD_OVERALLOC_COUNTが0になり、追加メモリーによる改善効果が頭打ちになる付近を候補として検討します。


11. PGAを多く使用しているプロセスを確認する

SELECT
    s.sid,
    s.serial#,
    s.username,
    s.program,
    p.spid,
    ROUND(p.pga_used_mem  / 1024 / 1024, 2) AS used_mb,
    ROUND(p.pga_alloc_mem / 1024 / 1024, 2) AS allocated_mb,
    ROUND(p.pga_max_mem   / 1024 / 1024, 2) AS max_mb
FROM
    v$process p
LEFT JOIN
    v$session s
ON
    s.paddr = p.addr
ORDER BY
    p.pga_alloc_mem DESC
FETCH FIRST 20 ROWS ONLY;

インスタンス全体のPGAが多い場合は、どのプロセスまたはセッションが使用しているかを確認します。

V$PROCESS_MEMORYを使用すると、PGAをSQL、PL/SQL、Javaなどのカテゴリ別に確認できます。


安全なメモリーチューニング手順

メモリーパラメータは、次の手順で変更します。

手順1:変更前の値を記録する

SELECT
    name,
    display_value
FROM
    v$parameter
WHERE
    name IN (
        'sga_target',
        'sga_max_size',
        'pga_aggregate_target',
        'pga_aggregate_limit'
    )
ORDER BY
    name;

手順2:OS側のメモリーを確認する

Linuxでは、次のような情報を確認します。

free -m
vmstat 1
grep -i huge /proc/meminfo

確認するポイントは次のとおりです。

  • 空きメモリーだけでなく、availableメモリー
  • スワップイン・スワップアウト
  • HugePagesの総数と空き数
  • 他のOracleインスタンスやアプリケーションの使用量
  • プロセス数の増加
  • コンテナやcgroupによるメモリー制限

手順3:Oracleのアドバイザを確認する

SGA全体       :V$SGA_TARGET_ADVICE
バッファキャッシュ:V$DB_CACHE_ADVICE
共有プール        :V$SHARED_POOL_ADVICE
PGA              :V$PGA_TARGET_ADVICE

手順4:一度に複数のパラメータを変更しない

たとえば、PGA不足が疑われる場合は、最初にPGA_AGGREGATE_TARGETだけを変更します。

ALTER SYSTEM SET pga_aggregate_target = 4G
SCOPE = BOTH;

数値は例です。実際の値は、物理メモリー、同時接続数、SQLワークロード、アドバイザの結果に基づいて決定してください。

手順5:変更後の差分を確認する

・処理時間
・待機イベント
・TEMP使用量
・物理読取り
・ハードパース
・One-pass、Multi-pass
・PGAの最大使用量
・OSのスワップ

手順6:改善しなければ元に戻す

ALTER SYSTEM SET pga_aggregate_target = <変更前の値>
SCOPE = BOTH;

オンライン変更が可能なパラメータであっても、縮小対象のメモリーがすぐに解放できない場合や、Oracle内部のリサイズ処理が完了するまで時間がかかる場合があります。V$SGA_RESIZE_OPSなどで変更状態を確認してください。


ORA-04031の原因と対処

エラーメッセージ

ORA-04031: unable to allocate ... bytes of shared memory

ORA-04031は、必要な共有メモリーを確保できなかった場合に発生します。

必ずしも共有プールだけで発生するわけではありません。エラーメッセージに表示されるヒープ名やプール名を確認し、共有プール、ラージ・プール、Streamsプール、In-Memory領域など、どの領域で不足したかを判断します。

主な原因

  • SGA全体が小さい
  • 共有プールなど特定のプールが小さい
  • 共有されないSQLが大量に存在する
  • 多数の子カーソルが生成されている
  • 大きな連続メモリーを確保できない
  • メモリーリークまたはOracle Databaseの不具合
  • Streamsプールなど、別のSGA領域が不足している

確認例

SELECT
    component,
    current_size,
    min_size,
    max_size
FROM
    v$sga_dynamic_components
ORDER BY
    current_size DESC;
SELECT
    request_misses,
    request_failures,
    last_failure_size
FROM
    v$shared_pool_reserved;

対処方針

1. アラートログとトレースファイルを確認
2. ORA-04031に表示されたプール名を確認
3. SQL共有状況や子カーソル数を確認
4. SGAおよび対象プールのサイズを確認
5. アドバイザを確認
6. 必要に応じてSGA_TARGETまたは対象プールを拡張
7. 再発する場合はOracle Supportへの調査依頼を検討

ALTER SYSTEM FLUSH SHARED_POOLについて

ALTER SYSTEM FLUSH SHARED_POOL;

このコマンドは、共有プール内の未固定オブジェクトをフラッシュします。

ただし、通常の根本対策として安易に実行すべきではありません。

実行後は、多くのSQLで再解析が必要になり、CPU負荷やハードパースが一時的に増加する可能性があります。共有プール不足の原因が、リテラルSQL、多数の子カーソル、無効化、メモリーリークなどである場合、フラッシュしても再発します。

影響を理解したうえでの一時的な復旧・切り分け手段として扱い、根本原因を調査してください。


ORA-04030の原因と対処

エラーメッセージ

ORA-04030: out of process memory when trying to allocate ...

ORA-04030は、Oracleプロセスがプライベートメモリーを確保できなかった場合に発生します。

Oracle公式のエラー説明では、OSメモリーの枯渇、またはプロセス単位のプライベートメモリー制限への到達が主な原因とされています。

主な原因

  • OSの物理メモリー不足
  • スワップ領域を含む仮想メモリー不足
  • プロセス単位のメモリー制限
  • ulimitやcgroupの制限
  • 1つのプロセスが大量のPGAを使用
  • 大量のPL/SQLコレクション
  • 非効率なソートやハッシュ処理
  • 過剰なパラレル実行
  • Oracle Databaseまたはアプリケーションのメモリーリーク

注意点

ORA-04030に対して、無条件にPGA_AGGREGATE_TARGETを増やすのは危険です。

PGA_AGGREGATE_TARGETを増やすと、各ワークエリアへ割り当てられるPGAが増え、OSメモリー不足を悪化させる可能性があります。

最初に、次の点を確認します。

・どのOracleプロセスでエラーが発生したか
・そのプロセスのPGA使用量
・ホスト全体のメモリー使用量
・OSのプロセス制限
・実行SQLやPL/SQL
・同時実行数とパラレル度
・アラートログ、トレースファイル

ORA-04036の原因と対処

エラーメッセージ

ORA-04036:
PGA memory used by the instance or PDB exceeds PGA_AGGREGATE_LIMIT

ORA-04036は、インスタンスまたはPDBのPGA使用量がPGA_AGGREGATE_LIMITを超えた場合に発生します。

確認する項目は次のとおりです。

SHOW PARAMETER pga_aggregate_limit
SELECT
    name,
    value,
    unit
FROM
    v$pgastat
WHERE
    name IN (
        'total PGA allocated',
        'maximum PGA allocated',
        'total PGA inuse'
    );

単純に上限を引き上げる前に、PGAを大量に使用したセッション、SQL、PL/SQL、パラレル実行を特定します。


OSメモリー枯渇とスワップを防ぐ

SGAとPGAの合計を、物理メモリーの限界近くまで設定してはいけません。

Oracle Databaseのメモリー以外にも、次の領域が必要です。

  • OSカーネル
  • OracleプロセスのPGA
  • Oracle Grid Infrastructure
  • ASM
  • ファイルシステムキャッシュ
  • 監視エージェント
  • バックアップソフト
  • セキュリティソフト
  • 他のデータベースやアプリケーション

Oracle公式のベストプラクティスでも、SGAとPGAの割当て合計を物理メモリーより小さくし、OSや他のプロセスに必要なメモリーを確保するよう説明されています。

ただし、「必ず物理メモリーの20%をOS用に残す」など、すべての環境に適用できる固定比率はありません。

OracleのPGAチューニングガイドでは、初期見積りの例としてOSなどに20%を確保する考え方が示されていますが、これはあくまで初期設計の例です。実際には、OS、接続数、PGAの変動、HugePages、ASM、バックアップ、監視ソフトなどを含めて設計します。

物理メモリー
   │
   ├─ OS・カーネル・通常ページ
   ├─ Oracle SGA
   ├─ Oracle PGA
   ├─ Grid Infrastructure・ASM
   ├─ バックアップ・監視プロセス
   └─ 予備メモリー

OSで継続的なスワップが発生すると、Oracle Databaseの応答時間が大きく悪化する可能性があります。SGA全体が実メモリーに収まるように設計することが重要です。


エディションによる違い

SGA、PGA、AMM、ASMMなどの基本的なメモリー管理機能は、Oracle Databaseの基本機能であり、Enterprise EditionとStandard Edition 2の両方で使用できます。

一方、In-Memory関連機能にはエディションおよびライセンス上の制限があります。

機能Enterprise EditionStandard Edition 2
SGA・PGAの基本機能利用可能利用可能
AMM利用可能利用可能
ASMM利用可能利用可能
自動PGAメモリー管理利用可能利用可能
Oracle Database In-Memory原則として有償オプション利用不可
Database In-Memory Base Level制限付きで利用可能利用不可

ライセンス条件は契約形態、クラウドサービス、Release Updateなどによって異なる場合があります。最終的な判断には、利用中の契約書および最新のOracle公式ライセンス情報を使用してください。


よくある質問

Q1. バッファキャッシュは大きいほど高速になりますか

一定の範囲までは、バッファキャッシュを大きくすることで物理読取りを削減できる可能性があります。

ただし、ワークロードで再利用されないブロックを大量に読み込んでいる場合や、すでに必要なデータが十分キャッシュされている場合は、拡張しても効果は限定的です。

V$DB_CACHE_ADVICEで、サイズを増やした場合の推定物理読取り数を確認してください。


Q2. ASMMではDB_CACHE_SIZEやSHARED_POOL_SIZEを0にすべきですか

特別な下限値が必要なければ、Oracle Databaseによる自動調整を優先できます。

ただし、特定のアプリケーションが必要とする最低サイズが分かっている場合は、個別パラメータに下限値を設定できます。

個別パラメータに設定した値は、ASMM環境では原則として最低保証値として扱われます。


Q3. PGA_AGGREGATE_TARGETを超えることはありますか

あります。

PGA_AGGREGATE_TARGETは目標値であり、絶対的な上限ではありません。また、すべてのPGAメモリーがこのパラメータで調整できるわけではありません。

絶対的な上限を設定する場合は、PGA_AGGREGATE_LIMITを使用します。


Q4. TEMP表領域を使用していればPGA不足ですか

必ずしもPGA不足とは限りません。

処理対象が非常に大きい場合、適切なPGAが設定されていてもOne-passで実行されることがあります。

次の情報を組み合わせて判断します。

  • workarea executions - onepass
  • workarea executions - multipass
  • extra bytes read/written
  • over allocation count
  • V$PGA_TARGET_ADVICE
  • 対象SQLの実行計画と処理データ量

特にMulti-passが継続的に発生している場合は、PGA不足や過剰な同時実行を疑います。


Q5. ORA-04031が発生したら共有プールをフラッシュすればよいですか

共有プールのフラッシュは一時的な切り分け手段であり、根本対策ではありません。

フラッシュ後にはSQLの再解析が集中する可能性があります。

次のような根本原因を調査してください。

  • 共有されないSQL
  • 多数の子カーソル
  • 共有プールまたは他のSGA領域の不足
  • DDLなどによるカーソル無効化
  • アプリケーション設計
  • Oracle Databaseの不具合やメモリーリーク

まとめ:Oracleメモリーチューニングの原則

Oracle Databaseのメモリーチューニングでは、次の点が重要です。

  1. SGAは共有メモリー、PGAはプロセス単位のプライベートメモリーとして理解する
  2. 物理I/Oが多いという理由だけでバッファキャッシュを増やさない
  3. ハードパースでは、共有プールのサイズとSQLの共有性を分けて調査する
  4. PGAではOptimal、One-pass、Multi-passの発生状況を確認する
  5. PGA_AGGREGATE_TARGETは上限ではなく目標値である
  6. 絶対上限にはPGA_AGGREGATE_LIMITを使用する
  7. LinuxでHugePagesを使用する場合はAMMではなくASMMを使用する
  8. アドバイザの予測値と実際の処理時間を基にサイズを決定する
  9. メモリー変更前後の統計情報を保存して比較する
  10. SGAやPGAを増やしてOSのスワップを発生させない
適切なメモリーチューニング
       =
Oracleの統計情報
       +
OSのメモリー状態
       +
SQL・ワークロードの分析
       +
変更前後の比較

メモリーサイズを勘や固定比率だけで決めるのではなく、V$DB_CACHE_ADVICEV$SHARED_POOL_ADVICEV$PGA_TARGET_ADVICEなどの情報と、実際のワークロードを基に判断することが、安定したOracle Database運用につながります。

※本記事はOracle Database 19cを対象としています。Release Update、OS、エディション、ライセンス、CDB/PDB構成によって動作や利用条件が異なる場合があるため、実環境への変更前に該当バージョンのOracle公式マニュアルを確認してください。


[参考]
パフォーマンス・チューニングの概要

Oracleのメモリ管理アーキテクチャ完全解説:SGAとPGAの構造、管理方式、監視方法
Oracle Databaseの安定運用・高パフォーマンス実現の鍵は、メモリの適切な管理にあります。本記事では、Oracleのメモリ構成(SGA・PGA・UGA・コード領域)をわかりやすく解説し、メモリ管理方式(AMM、ASMM、手動)と監…

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

タイトルとURLをコピーしました