
DFS lock handle - 日本エクセム株式会社 Oracle待機イベント情報
目次[非表示]
- 1.基本情報
- 2.待機パラメータと待機時間
- 3.チェックポイントとソリューション
- 4.豆知識
- 4.1.Sequence属性に応じた待機イベント
- 4.2.row cache lock競合
- 4.3.SQ Lock競合
- 4.4.SV Lock競合
基本情報
DFS lock handleは要求されたGlobal lockのlock handleを待っている待機イベントです。このlock handleはglobal lockと同じです。 lock handleを取得するとglobal lockを所有した状態でlock conversionやlock releaseなどの複数のタスクを実行することができます。 global lockはDLMによって管理されます。
DFSはDistributed File Systemの略で、Oracle製品の歴史と関連している用語であると考えられます。Oracle 10g RACの機能が完成されるまで、Oracleはかなりの期間の間に分散データベースを実装しており、最初の分散データベースは、分散ファイルシステムをベースにしていたことが知られています。このような理由から、これまでいくつかのglobal lock競合ではまだDFSという用語を使用しています。
ほとんどのlockのグローバル競合は、シングルインスタンス環境で発生するような待機イベント名に観察されます。例えば、グローバルTM lock競合はenq:TM – contentionイベントで観察され、グローバルSQ lock競合はenq:SQ – contentionイベントに観察されます。これらとは異なり、DFS lock handle待機イベントで観察されている代表的なglobal lock競合はSV lock競合とCI lock競合があります。
待機パラメータと待機時間
待機パラメータ
待機時間
セッションがDLMからlock handleを所有するまでloopをすることで待機します。loopごとに0.5秒ずつ待機します。
チェックポイントとソリューション
SequenceのCache Sizeの増加について
DFS lock handleイベントはOPSやRAC環境では、バッファキャッシュの同期を除くrow cacheやlibrary cacheの同期のためにlockを獲得する過程で待機するイベントです。複数のノード間でのシーケンスの順序を保証するには、グローバルにlockを獲得しなければならないため、この過程でDFS lock handle待機が発生するようになります。SV lockを獲得する過程で発生するDFS lock handle待機イベントのP1、P2の値はenq:SQ – contention待機イベントと同じです。(P1= mode+ namespace、P2= object#)したがってP1の値からSV lockかどうかを確認することができ、P2の値を使用して任意のシーケンスに対して待機が発生していることを確認することができます。SV lock競合の問題が発生した場合の解決策は、SQ lockの場合と同様です。キャッシュサイズを適切に増加するのが唯一の解決策です。
RACの場合SequenceにCACHE+ NOORDER属性の付与
RACのようなマルチノード環境では、シーケンスのキャッシュサイズがパフォーマンスに与える影響は、シングルノード環境よりもはるかに大きくなります。したがって、可能であれば、CACHE+ NOORDER属性を付与して、十分な大きさのキャッシュサイズを付与することが望ましいことになります。もし順序を保証することが、必要であればCACHE+ ORDER属性を付与します。しかし、この場合、順序を保証するために、インスタンス間でデータ交換が絶えず発生します。これにより、NOORODER属性を付与した場合よりも性能面で不利となります。
豆知識
Sequence属性に応じた待機イベント
一つ注意することはCACHE属性を付与していない場合には、ORDER属性を使用するかどうか、またはRAC環境かどうかとは無関係に、常にrow cache lockイベントを待機するということです。 Row cache lockは、グローバルに使用可能なlockであり、シングルインスタンス環境やマルチインスタンス環境で同じように使用されます。シーケンスの作成時に付与された属性に応じた待機イベントを整理すると、次の通りです。
row cache lock競合
キャッシュ(Cache)属性を付与していないシーケンスを同時に多くのプロセスが使用している場合、row cache lockイベント待ちが広く発生することがあります。キャッシュを使用していないシーケンスのnextvalを呼び出すと、毎回Dictionary情報が変更されるべきであるためrow cache lockをSSXモードで獲得しなければなりません。SSXモード間の相互互換性がないため、この過程で競合が発生することにります。Row cacheダンプとV$ ROWCACHE_PARENTビューから正確なオブジェクトの情報を確認する方法を使用してrow cache lockの情報を調べてみましょう。
次に、nextvalを大量に呼び出しながらrow cache lockがどのように獲得されるかを観察してみましょう。
以下のように10000回の間seq_seq.nextvalを呼び出します。
Shared Sub-Exclusiveモードの意味は、オブジェクト全体には、Sharedモードで、オブジェクトの一部には、Exclusiveモードでロックを獲得することです。 Seqneuce.nextval呼び出しによってシーケンスディクショナリ情報が変更されている場合には、シーケンス自体を変更させるのではなく、シーケンスの「次の値」だけを変更させるので、SSXモードでrow cache lockを獲得するものです。
シーケンスを除いては、row cacheの情報をこのように頻繁に変更することはほとんどありません。したがってrow cache lock待機が表示される場合、シーケンスにNOCACHE属性が付与されていないか確認する必要があります。 OPS環境でのシーケンスの順序を完全に保証するためにNOCACHE属性にシーケンスを作成した場合にrow cache lock待機現象が表示される場合が多くあります。 RAC環境では、CACHE属性を使用しつつ、同時にノード間のシーケンスの順序を完全に保証することが可能です。
SQ Lock競合
CACHE属性が付与されたシーケンスのnextvalを呼び出し中に、SQ lockをSSXモードで獲得しなければなりません。同時に多くのセッションがSQ lockを獲得するために競争する過程で競合が発生した場合enq:SQ – contentionイベントを待機することになります。 enq:SQ – contentionイベントのP2の値は、シーケンスのオブジェクトIDです。したがってP2の値を利用してDBA_OBJECTSビューと結合する任意のシーケンスに対して待機現象が発生していることがわかります。
シーケンスの作成時に付与されたキャッシュサイズが小さい場合にenq:SQ – contention待機が増加する傾向があります。キャッシュサイズが小さい場合には、メモリにあらかじめキャッシュされた値が急速に排出され、キャッシュの値が排出された場合には、ディクショナリ情報を物理的に変更して再キャッシュする作業をしなければなりません。その中でSQ lockを継続して取得する必要があるため、enq:SQ – contentionイベントの待機時間がそれだけ増加します。 SQ lock競合によるパフォーマンスの問題は、CACHE属性を大きくすることで問題を解決することができます。残念ながら、シーケンスの作成時にキャッシュ・サイズのデフォルト値が20で小さく設定されています。したがって使用量が多いと予想されるシーケンスを生成する際にCACHE値を1000以上の大きな値で確保することが望ましいのです。
たまに一度に多くのセッションが同時に生成されるときにenq:SQ – contention待機イベントが発生する場合があります。その理由は、V $ SESSION.AUDSID(Auditing session id)列の値がシーケンスを利用して生成されることから発生します。 Oracleは、新しいセッションが作成されるとSYS.AUDSES $という名前のシーケンスのnextvalを利用してAUDSID値を生成します。 SYS.AUDSES $シーケンスのキャッシュ・サイズは、デフォルトで20に設定されています。一度に多くのセッションが同時に接続する場合には、SYS.AUDSES $シーケンスのキャッシュ・サイズを10000程度大きく増やすことで、enq:SQ – contention待機問題を解決することができます。
RACでは、シーケンスの作成時にCACHE属性を付与した状態で、ORDER属性を付与しないと、各ノードが他の範囲のシーケンス値をメモリにキャッシュします。たとえば、2つのノードからなるRAC環境でCACHE 100属性にシーケンスを生成する場合、1回のノードは、1〜100回を使用して、2回のノードは、101〜200回を使用することになります。もし両ノード間の両方順次増加シーケンスを使用するには、以下のようにORDER属性を付与しなければなりません。
SV Lock競合
SV lockはSequence Value lockの略でRACでORDER属性のシーケンス値を保護するために使用されるlockです。
CACHE + NOORDER属性のシーケンスが性能面では、最も有利です。しかし、NOORDER属性のシーケンスは、RACシステム内のノード間の順序を保証することができないという欠点があります。例えば、キャッシュサイズが100であり、NOORDER属性が付与されたシーケンスを2ノードで構成されるRACシステムで使用すると、ノード1に1〜100番、ノード2に101〜200回のシーケンスのキャッシュを使用することになります。したがって、クライアントがRACシステムに接続して、そのシーケンスを使用すると、シーケンスの値が「1、2、101、3、102、103 “のように、両方のノードのキャッシュ値が混在して抽出されます。ほとんどの状況では、このような現象が問題はありませんが、もしシーケンス値が必ず順次抽出する必要がある制約が必要な場合はORDER属性を付与することにより、このような現象を解消することができます。 ORDER属性のシーケンスでは、RACのすべてのノードが同じキャッシュ値を保持します。つまり、ノード1も1〜100番、ノード2も1〜100回のシーケンスのキャッシュを使用して、両方のノードは、SV lockを利用して、グローバルシーケンスの同期を実行します。
ORDER属性を使用する場合、シーケンスの値を抽出するたびにSV lockのグローバル同期処理が発生するのでNOORDER属性を使用するよりも性能面ではかなり不利です。しかし、NOCACHE属性を付与するよりもはるかに性能面では有利です。したがってRACシステムでは、可能な場合、CACHE + NOORDERプロパティを使用して、順序の保証が必要な場合に限りORDER属性を付与するのが得策です。 NOCACHE属性は、可能な限り使用してはなりません。
シーケンスキーの値が見つからない(Miss)場合、常に連続して増加しなければならないという前提条件のためにNOCACHE属性のシーケンスを使用している場合がしばしばあります。これはまず、性能面で非常に不利な選択となります。特にRACのような分散データベース環境では、NOCACHE属性のシーケンスが及ぼす悪影響は致命的なことになります。注意点としては、シーケンス値の欠落は絶対避けられないものであることです。 NOCACHE属性を付与しても、シーケンス値の欠落は常に発生します。例えば50万件のデータのキー値をシーケンスを利用して生成している途中にファイルスペースの不足によりロールバックが発生した場合は、この50万のシーケンスキー値は、不足している状態になります。このような理由から、NOCACHE属性のシーケンスは絶対に使用しないことを原則とすることを推奨します。
CACHE + ORDER属性が付与されたシーケンスである場合には、OracleはSQ lockではなく、SV lockを使用して同期を実行します。つまり、Order属性が付与されたSequenceに対してnextvalを呼び出すと、SSXモードでSV lockを獲得しなければなりません。 SV lockを獲得する過程で競合が発生した場合には、row cache lockイベントやenq:SQ – contentionイベントとは全く異なるDFS lock handleという名前のイベントを待機することになります。このような理由から、V $ EVENT_NAMEビューには、 “enq:SV – contention”のような名前のイベントが存在しません。