共有プール・ラッチは共有プールの基本的なメモリー構造であるヒープを保護する役割をします。pool待機イベントで待機します。ヒープと関連した一連の作業は非常に早く完了するので、普通の場合は共有プール・ラッチでの競合は発生しません。pool待機イベントが増加する可能性があります。共有プール・ラッチは全体インスタンスに一つだけ存在します。これは共有プールの基本メモリー構造であるヒープのアーキテクチャーによるものです。一つの共有プール・ラッチを獲得するため競合が発生するようになります。ハード解析の発生が激しい場合は、チャンクが分割される現象が頻繁に発生します。これによって空きリストに数多くの小さな空きチャンクができる現象が発生します。このような現象を共有プールの断片化と言います。共有プールの断片化によって空きリストを探索する時間が長くなり、その分共有プール・ラッチを保有する時間が増えます。共有プールの断片化は共有プール・ラッチ競合を発生させる根本的な原因であり、ORA-4031エラーを発生させる原因でもあります。ハード解析が発生すると、新しいSQL情報を入れるチャンクを割当られるために空きリストを探索しなければなりません。pool待機イベントが発生します。ハード解析が過度に発生するシステムで共有プール・ラッチ待機イベントを減らすために共有プールのサイズを増やすのは非常に危険な発想です。共有プールが大きくなると、それだけの空きリスト数と空きリストで管理しなければならない空きチャンクの数も増えるためです。従って、空きリストを探索するために共有プール・ラッチを獲得する時間が長くなります。pool待機イベントの待ち時間も増えていきます。待機パラメータP1:ラッチのアドレスP2:ラッチ番号(V$LATChNAME.LATCH#と同一)。ラッチ番号に該当するラッチ名を確認するためには、下記のSQLを実行します。&p2_value;P3:試行回数。チェックポイントとソリューションサブ・プールを使用するOracle9i以降からは、共有プールをいくつかのサブ・プール(最大7個まで)で分けて管理することができます。_KGHDSIDX_COUNT隠しパラメータを利用すればサブ・プール数を管理することができます。OracleはCPU数が4以上で、共有プールの大きさが250MB以上の場合、_KGHDSIDX_COUNT値の数だけサブ・プールを生成し、共有プールを管理します。サブ・プールは独立的な共有プールとして管理されており、独自の空きリスト、LRUリスト、共有プール・ラッチを持ちます。従って、共有プールが大きい場合にはサブ・プールを分けて管理することによって共有プール・ラッチ競合を減らすことができます。共有プールのサイズを小さくするハード解析によって共有プール・ラッチ競合が発生する場合、他の解決策としては共有プールのサイズを小さくすることがあります。共有プールの領域が減った分、空きリストの空きチャンク数も減少し、空きリスト探索に所要する時間も短くなるためです。この方法を使った場合、ORA-4031エラーが発生する可能性が高くなります。追加のハード解析が多発する可能性があります。共有プールに永続的にキャッシュさせる方法があります。SHARED_POOLコマンドを使っても共有プールからフラッシュされなくなります。利用されるオブジェクトをメモリーにキャッシュするのも一つの方法になります。共有カーソル機能を使用する共有カーソル機能は、リテラルを使ったSQL文が自動でバインド変数を使うように置き換えて、カーソルを共有させる機能です。共有カーソル機能は既存のリテラルSQLをバインド変数に変えることができない場合推奨されます。この機能を使う場合、既存SQL文の実行計画が変更される可能性もあるため、十分なテストを行ってから適用することが望ましいです。共有プールはSGAのコンポーネントの一つです。下記のコマンドでSGAのコンポーネントを確認することができます。bytes共有プールはSGA領域の中で、可変する領域に属します。プール、ラージ・プール、ストリーム・プールで構成されています。共有プールは様々な種類のメモリー領域に分けられます。代表的なものは、ライブラリ・キャッシュとディクショナリ・キャッシュです。共有プールがどんな領域に分けられているのかはV$SGASTATビューで確認することができます。599個のメモリー領域に分けられる。大きいの順で20個だけ問い合わせてみると下記の結果になる。--各メモリー領域の大きさは動的に変わる。1282376共有プールの構成要素は大きく分けて、次のように区分されます。リソースは共有プールの永続領域に割り当てられます。SQL文を実行するのに必要な全てのオブジェクト(SQL、表、ビュー、プロシージャなど)に関する情報を管理します。ディクショナリ・キャッシュとも言い、Oracleが使うディクショナリー情報を管理します。動的なメモリー割当のためにOracleは予約領域を割り当てておきます。共有プールはヒープと呼ばれるメモリー管理手法で管理されます。共有プールのヒープからメモリーの割当てを要求する全てのプロセスは必ず共有プール・ラッチを獲得しなければなりません。共有プール・ラッチを獲得します。必要なメモリーが割当られるまで保有していなければなりません。ラッチを獲得するための競合が発生します。pool待機イベントで待機します。Oracle9i以上からは共有プールをいくつかのサブ・プール(最大7個まで)に分けて管理することができます。_KGHDSIDX_COUNT隠しパラメータを利用すればサブ・プール数を管理することができます。_KGHDSIDX_COUNT値の数だけサブ・プールを作って共有プールを管理します。LRUリスト、共有プール・ラッチを持ちます。従って、共有プールが大きい場合には、サブ・プールに分けて管理することをお勧めします。することで共有プール・ラッチ競合を減らすことができます。ヒープとヒープ・ダンプヒープに対する基本的な項目を整理してみます。ヒープ・マネージャにより管理されている、Oracleの最も基本的なメモリー割当方法です。ヒープ・マネージャはメモリー・マネージャが提供するサービスを利用し、動的にメモリーを管理します。ライブラリ・キャッシュ・マネージャはヒープ・マネージャでライブラリ・キャッシュを管理します。共有プールは基本的に一つの最上位のヒープを持ち、最上位のヒープはまたいくつかのサブ・ヒープを含みます。サブ・ヒープはまたさらにそれ自身のサブ・ヒープを含みます。ヒープとサブ・ヒープは基本的に同じ構造を持ちます。ヒープ内にある一つのチャンクは、サブ・ヒープに対してのポインタの役割をします。Oracle9i以降からは適切な環境が整っていれば、様々な最上位のヒープを持つことができます。ヒープはいくつかのエクステントをリンクされたリスト形式で持ちます。一つのエクステントは物理的に一つのグラニュルを使います。1GB以上であれば16MBになります(Oracle10g基準)。一つのエクステントは複数のチャンクで構成されます。それぞれのチャンクの使用状況はX$KSMSPビューで確認することができます。サブ・ヒープの場合、エクステントの大きさは変動します。共有プールのメモリーはグラニュルを追加し、積み重ねていく形で割り当てられるため、ヒープと言われています。freeabl(Freeable:セッションやコールの間のみ必要なオブジェクトが使用している状態)、perm(Permanent:永続、再生成不可)になります。freeあるいはrecr状態のチャンクは再使用が可能です。ヒープは空きリストを管理するバケット表を持ちます。それぞれのバケットは、リンクされたリスト形式で空きチャンクに対する空きリストを持ちます。一つのヒープには、合計255個のバケットが存在しており、バケットの空きチャンクの大きさはバケット番号の増加に伴って順次に増加します。ヒープはLRUリストを持っています。LRUリストは現在使用中でない、つまり再生成可能なチャンクのリストです。最上位のヒープは予約空きリストという別の空きリストを管理します。予約空きリストは大きいオブジェクトを保存する共有プール内の予約領域に関する空きリスト情報を管理します。ヒープ・ダンプを取ってみると、ヒープの構造を確認することができます。下記のコマンドを実行し、USER_DUMP_DESTにヒープ領域に関するダンプ・ファイルを確認します。2';次は、結果ファイルの内容です。使い切ってしまうと、LRUリストを使用する。上記のようにヒープ・ダンプを取ることによって、ヒープの正確な構造情報を得ることができます。各ヒープはまたサブ・ヒープ構造を持ちます。ヒープは自分が保持している特定のチャンクにサブ・ヒープのアドレスを保存してサブ・ヒープの位置を管理します。ヒープ・ダンプで分かるように、次のような”ds”値が設定されているチャンクがサブ・ヒープの位置を保存しているチャンクです。ds=c0000000993293e8ds値はヒープ・ディスクリプタという意味であり、ds=c0000000993293e8がサブ・ヒープのアドレスを示します。下記のコマンドで、該当サブ・ヒープのダンプを取ることができます。0xc0000000993293e8';下記のサブ・ヒープのダンプ内容を確認すると、ヒープ・ダンプとほとんど同じ形式を持っていることが分かります。エクステントの大きさが変動する点と、予約空きリストを管理しないという点を除けば、サブ・ヒープは最上位のヒープと同じ構造を持ちます。pool待機イベントが発生していることが確認できます。pool待機イベントが最も多く発生していることが確認することができます。ハード解析の回数が全体解析の回数と同じ数値になるほどハード解析が頻繁に発生していることも確認できます。Value=0共有カーソル機能を使用することによってハード解析を避けることができます。下記のようなコマンドでCURSOR_SHARINGパラメータ値をFORCEに変更すると、全てのリテラルSQLを自動で共有可能なSQLに変換することができます。SCOPE=MEMORY;下の結果は共有カーソルを設定した後の性能測定結果です。pool待機イベントが解消されており、ハード解析の回数が大きく減少したことが確認できます。Value=2(cs)ハード解析による性能低下現象分析ケースII同時ユーザーが多いOLTPおよびWEB環境で、過剰なリテラルSQLの使用は、性能上の深刻な問題を引き起こす場合が多いです。MaxGaugeを活用して、リテラルSQLの過度な使用による性能低下問題の原因を解析してみます。Events」が急増していることを簡単に確認できます。Events」の推移グラフ(待機時間)待機イベントの検出および分析アクティブ・セッションの急増によるスローダウンの原因を究明するため、問題時点(10時17分)の待機イベントの発生内容を確認してみます。freeであることが分かりました。free待機イベントの関連性を確認するために、発生パターンを比較してみました。Session」の推移と非常に似ていることが分かります。free待機イベントは、問題が発生した時点の待機時間の約74%(全体392.53秒中、291.91秒)を占めています。free待機イベントの急激な発生と関連しているとのことが考えられます。cache)待機イベントが多く発生していることが確認できます。同時に発生した場合は、ハード解析がその原因である可能性が高いです。elapsed統計値の推移を確認してみます。(hard)統計値が200回/秒発生したことが確認できます。遅延が発生したと考えられます。Client」プログラムであることが確認できます。free待機イベントの急増によるアクティブ・セッションの急増。↓リテラルSQLによるハード解析の過剰な実行がスローダウンの原因。Page本サイトに掲載されている情報は日本エクセム株式会社が提供しています。