Oracleデータベースのメモリ構造とプロセス管理の基礎
Oracleデータベースシステムを効果的に運用し、その性能を最大限に引き出すためには、内部のメモリ構造とプロセス管理の理解が不可欠です。本稿では、主要なメモリコンポーネント、プロセスの役割、およびそれらがどのように連携して機能するかについて解説します。
システムグローバル領域 (SGA) の構成要素
SGA(System Global Area)は、Oracleインスタンスが起動する際に割り当てられる共有メモリ領域であり、複数のデータベースプロセスで共有されます。SGAの主要なコンポーネントは以下の通りです。
1. 共有プール (Shared Pool)
共有プールは、SQL文の実行計画、データディクショナリ情報、ライブラリキャッシュなどを保持します。これにより、同じSQL文が繰り返し実行される際に、解析のオーバーヘッドを削減し、データベースの応答性を向上させます。
-- 共有プールの現在のサイズを確認
SELECT component, current_size, user_specified_size FROM v$sga_dynamic_components WHERE component = 'shared pool';
2. データベース・バッファ・キャッシュ (Database Buffer Cache)
この領域には、データファイルから読み込まれたデータブロックが一時的に格納されます。データがメモリ上にあることで、ディスクI/Oの発生を最小限に抑え、データアクセスを高速化します。
バッファキャッシュ内の各バッファの詳細はv$bhビューから確認できます。特に「TCH (Touch Count)」列は、そのバッファがアクセスされた回数を示し、値が高いバッファは「ホットブロック」として、頻繁に利用されていることを意味します。
-- バッファキャッシュ内のバッファ情報を確認
SELECT file#, block#, status, class, tch FROM v$bh;
-- データベース・バッファ・キャッシュの現在のサイズを確認
SELECT component, current_size, user_specified_size FROM v$sga_dynamic_components WHERE component = 'DEFAULT buffer cache';
3. REDOログ・バッファ (Redo Log Buffer)
データベースに加えられた全ての変更(DMLやDDL)は、まずこのREDOログ・バッファに一時的に記録されます。その後、REDOログファイルに書き込まれ、データベースのリカバリ機能の中核を成します。
-- REDOログ・バッファのサイズを確認
SHOW PARAMETER log_buffer;
4. その他のSGAコンポーネント
上記以外にも、大規模なソートやハッシュ結合に使用される「Large Pool」、Javaアプリケーションのメモリを管理する「Java Pool」、Oracle Streams関連の操作に使用される「Streams Pool」など、特定の用途に応じたコンポーネントが存在します。これらのサイズもv$sga_dynamic_componentsビューで確認可能です。
-- SGAの全コンポーネントのサイズ情報を確認
SELECT component, current_size, user_specified_size FROM v$sga_dynamic_components ORDER BY component;
SGAの動的な管理
Oracleは、sga_targetおよびsga_max_sizeパラメータに基づいてSGAを動的に管理します。sga_targetはSGAの目標サイズを設定し、sga_max_sizeはSGAが拡張できる最大サイズを定義します。システム負荷に応じて、OracleはSGA内の各コンポーネントのサイズを自動的に調整します。たとえば、あるコンポーネント(例: Shared Pool)の要求が増加すると、別のコンポーネント(例: Buffer Cache)のサイズが減少するといった調整が行われることがあります。これは、sga_targetで設定された総メモリ内で最適なバランスを維持するためです。
-- SGAの動的フリーメモリの状況を確認
SELECT * FROM v$sga_dynamic_free_memory;
-- SGAの目標サイズと最大サイズを確認
SHOW PARAMETER sga_target;
SHOW PARAMETER sga_max_size;
-- SGAコンポーネントのリサイズ操作履歴を確認
SELECT component, oper_type, parameter, initial_size, final_size, status, start_time, end_time FROM v$sga_resize_ops ORDER BY start_time DESC;
プログラムグローバル領域 (PGA)
PGA(Program Global Area)は、各サーバープロセスに専用で割り当てられる非共有のメモリ領域です。SGAとは異なり、PGAは個々のユーザーセッションやバックグラウンドプロセスに特有の作業空間を提供します。Oracle 9i以降のバージョンでは、pga_aggregate_targetパラメータによってPGAの総量が自動的に管理されます。
PGAの主な機能は以下の通りです。
- ソート操作(
ORDER BY、GROUP BYなど)のためのメモリ - ハッシュ結合操作のためのメモリ
- カーソル情報やセッション固有の変数など、セッションの状態を保持する領域
pga_aggregate_targetが設定されている場合、Oracleは各サーバープロセスのPGAを自動的に調整し、メモリの効率的な利用を促進します。
-- PGA自動管理ポリシーを確認 ('AUTO'であれば自動管理)
SHOW PARAMETER workarea_size_policy;
-- PGAの集約目標サイズを確認 ('0'はOracleが自動設定することを示す場合がある)
SHOW PARAMETER pga_aggregate_target;
-- 各セッションのPGA使用状況を確認
SELECT
s.username,
p.pga_used_mem / (1024 * 1024) AS pga_used_mb,
p.pga_alloc_mem / (1024 * 1024) AS pga_allocated_mb,
p.pga_max_mem / (1024 * 1024) AS pga_max_mb
FROM v$process p
JOIN v$session s ON p.addr = s.paddr
WHERE s.username IS NOT NULL
ORDER BY p.pga_used_mem DESC;
SQL処理フェーズと実行計画
SQL文の処理は、一般的に「解析 (Parse)」、「実行 (Execute)」、「フェッチ (Fetch)」の3つのフェーズに分かれます。
- 解析 (Parse): SQL文の構文チェック、セマンティックチェック、そして最も効率的なデータアクセス方法である実行計画の生成が行われます。
- 実行 (Execute): データベースは生成された実行計画に従い、データへのアクセスと結果セットの生成を行います。
- フェッチ (Fetch): クライアントアプリケーションは、実行フェーズで生成された結果セットを取得します。
v$sqlビューは、共有プールにキャッシュされているSQL文とそのメタデータを提供します。これにより、過去に実行されたSQLの情報を確認できます。
-- 共有プール内のSQL文を確認(例: 特定のキーワードを含むSQL)
SELECT sql_id, sql_text, parse_calls, executions, loads FROM v$sql WHERE sql_text LIKE '%UPDATE SYS.JOB$%' AND sql_text NOT LIKE '%v$sql%';
-- 特定のSQL_IDに対する実行計画を表示
-- 'aq8yqxyyb40nn' はSQL_IDの例です。0はCHILD NUMBERを示します。
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('aq8yqxyyb40nn', 0, 'ALLSTATS LAST'));
最適な実行計画を生成するためには、データベースオブジェクト(テーブル、インデックスなど)の統計情報が正確かつ最新であることが極めて重要です。
SQLのパフォーマンス問題を詳細に分析するためには、SQLトレース機能が非常に有用です。これにより、SQL文の実行における詳細な統計情報が取得できます。
-- 現在のセッションのSQLトレースを開始
ALTER SESSION SET SQL_TRACE = TRUE;
-- 分析したいSQL文を実行
-- SQLトレースを停止
ALTER SESSION SET SQL_TRACE = FALSE;
パラメータファイルと制御ファイル
Oracleインスタンスの動作は、パラメータファイルと制御ファイルによって定義されます。
1. パラメータファイル (SPFILE/PFILE)
データベースインスタンスの初期化パラメータが格納されています。SPFILE(サーバーパラメータファイル)はバイナリ形式で、インスタンスによって動的に変更・永続化が可能です。PFILE(初期化パラメータファイル)はテキスト形式です。
# パラメータファイルの典型的な場所: $ORACLE_HOME/dbs
cd $ORACLE_HOME/dbs
ls -l spfile*.ora
# SPFILEの内容を一部テキストで表示 (完全に可読ではありません)
strings spfileorcl.ora | head -n 20
2. 制御ファイル (Control File)
制御ファイルは、データベースの物理構造(データファイルのパス、REDOログファイルのパス、アーカイブ情報、チェックポイント情報など)に関する重要なメタデータを格納しています。データベースの整合性を維持し、リカバリ操作において不可欠なファイルです。
# 制御ファイルの典型的な場所: /oradata/orcl (またはデータベースのデータディレクトリ)
cd /oradata/orcl
ls -l control01.ctl
# 制御ファイルの内容を一部テキストで表示 (完全に可読ではありません)
strings control01.ctl | head -n 20
SQL解析の種類:ハード解析とソフト解析
- ハード解析 (Hard Parse): 新しいSQL文が実行され、共有プール内にその実行計画がまだ存在しない場合に発生します。構文チェック、セマンティックチェック、最適化、実行計画の生成といった、CPUとI/Oを多く消費するプロセスを含みます。
- ソフト解析 (Soft Parse): すでに共有プールにキャッシュされているSQL文とその実行計画が再利用される場合に発生します。実行計画の再生成が不要なため、ハード解析に比べてはるかに高速です。
データベースのパフォーマンスを最適化するためには、ハード解析を可能な限り減らし、ソフト解析の比率を高めることが重要です。
物理I/Oと論理I/O
- 物理I/O (Physical Read): データがディスクからデータベース・バッファ・キャッシュに読み込まれる操作です。ディスクアクセスは高コストなため、削減が重要です。
- 論理I/O (Logical Read / Consistent Read): データがデータベース・バッファ・キャッシュから読み込まれる操作です。データが既にメモリに存在するため、物理I/Oよりもはるかに高速です。
パフォーマンスチューニングでは、物理I/Oを最小限に抑え、論理I/Oの効率を高めることが目標となります。テストのためにバッファキャッシュをクリアすることもできますが、本番環境では注意が必要です。
-- データベース・バッファ・キャッシュの内容をフラッシュ(テスト環境でのみ推奨)
ALTER SYSTEM FLUSH BUFFER_CACHE;
Oracleプロセスの構造
Oracleデータベースシステムは、多数のバックグラウンドプロセスと、ユーザー接続を処理するサーバープロセスで構成されています。
サーバープロセス (Server Process)
各ユーザー接続は、通常、専用のサーバープロセスによって処理されます。このサーバープロセスは、ユーザーからのSQLリクエストを受け取り、SQLの実行、データアクセス、結果のクライアントへの返却などを担当します。
オペレーティングシステムレベルでは、サーバープロセスは`SPID` (Server Process ID) という一意の識別子を持ちます。データベースレベルでは、ユーザーセッションは`SID` (Session ID) と`SERIAL#` (Serial Number) で識別されます。
# オペレーティングシステムレベルでOracleのサーバープロセスを確認
ps -ef | grep ora_ | grep -v grep
-- アクティブなデータベースセッションを確認
SELECT sid, serial#, username, status, program FROM v$session WHERE username IS NOT NULL;
-- データベースセッションに対応するOSプロセスID (SPID) を確認
SELECT
p.spid,
s.sid,
s.serial#,
s.username,
s.program
FROM v$process p
JOIN v$session s ON p.addr = s.paddr
WHERE s.username IS NOT NULL AND s.type = 'USER'
ORDER BY s.sid;
PGAの隠しパラメータ
PGAの自動管理は通常`pga_aggregate_target`によって行われますが、より詳細な挙動を制御するために、いくつかの隠しパラメータが存在します。これらのパラメータは通常、Oracleサポートの指示がない限り変更すべきではありません。
-- 隠しパラメータを検索する汎用クエリ
-- 例: '_pga_max_size' を検索する場合は、'&par' に '_pga_max_size' を入力して実行
SELECT x.ksppinm AS parameter_name, y.ksppstvl AS value, x.ksppdesc AS description
FROM SYS.x$ksppi x, SYS.x$ksppcv y
WHERE x.inst_id = USERENV ('Instance')
AND y.inst_id = USERENV ('Instance')
AND x.indx = y.indx
AND x.ksppinm LIKE '%&par%';
1. _PGA_MAX_SIZE
このパラメータは、単一のサーバープロセスが使用できるPGAの最大サイズを制限します。これは、`pga_aggregate_target`で設定された全体の予算内で、個々のプロセスが過度にメモリを消費しすぎないようにするためのガードレールとして機能します。
2. _SMM_MAX_SIZE
単一のシリアル(非並列)実行操作(例: ソート、ハッシュ結合)における個別の作業領域の最大サイズを制限します。SQL文が複数のソート操作を含む場合、それぞれのソート操作にこの制限が適用されます。
3. _SMM_PX_MAX_SIZE
並列実行時における、すべての並列サーバープロセスが使用できる作業領域の最大合計サイズを制限します。個々の並列実行操作の作業領域は`_SMM_MAX_SIZE`の制限を受ける一方で、並列操作全体としてのPGA消費総量がこのパラメータによって制御されます。