Gc cr/current block busy

目次

基本情報

 

gc cr/current block busyイベントは、gc cr/current requestイベントのFixed-upイベントで、ホルダーのノードからブロック画像を転送される過程で、競合が発生したことを意味します。gc cr/current requestイベントがgc cr/ current block busyイベントに変更された流れは、以下の通りです。

・リクエストノードのユーザプロセスが特定のデータブロックを読もうとします。
・ユーザプロセスは、データブロックの適切なバージョンがローカルバッファキャッシュにないことを確認し、
 マスターノードのLMSプロセスにブロック転送を要求します。ユーザプロセスは、応答を受信するまで、
 gc cr/ current requestイベントを待機します。
・マスターノード(つまり、ホルダーノード)のLMSプロセスは、要求されたブロックに対してBLロックを共有モードで
 獲得することができなければなりません。もし必要なモードのロックを獲得する過程で遅延が発生した場合、要求ノードに
 ブロックを送信しますが、ブロックを読み込む過程で競合(Contention)が発生したように知らせます。
・ユーザプロセスは、ブロックを送信された後に応答メッセージから競合が発生したことを確認し、gc cr/ current 
 requestイベントをFixed-upイベントgc cr/ current block busyイベントに変更します。

gc cr/current block busy待機イベントは、ブロックを送信される過程で、競合に起因する遅延(Delay)が発生したことを意味します。Oracleは、「競合(Contention)」と「混雑(Congestion)」という二つの理由により、グローバルキャッシュの同期過程で遅延が発生すると定義しています。競合(Contention)が遅延の発生事由である場合には、「Busy」という用語を使用し、混雑(Congestion)が発生事由である場合には、「Congested」という用語を使用していることを覚えておきましょう。

ホルダーノードのLMSプロセスがブロックを送信する過程で競合による遅延が発生する理由は、次のようなものがあります。

1.要求されたブロックがローカルプロセスによって現在使用されている場合、現在の変更されているブロックには、
  バッファロック(Buffer Lock)が排他モードで獲得された状態なので、LMSプロセスは、ブロックの変更が完了
 するまで待機しなければなりません。 Updateステートメントによって変更しているか、Selectステートメント
 によって、ディスクからバッファキャッシュにロードされている場合を含みます。
2.REDOフラッシュ(Flush)過程が発生した場合。ホルダーノードのローカルプロセスによって変更された後、
 まだCommitが行われていないブロックを要求ノードに転送するには、ブロックの変更をREDOログに記録しなければ
 なりません。このプロセスを「REDOフラッシュ」と呼びます。この過程で遅延が発生すると、ホルダーのノードでは、
 gcs log flush syncイベントの待機時間が高かったり、gc cr block flush time統計値やgc current block 
 flush time統計値が高く出てきます。LMSプロセスがブロック転送のためにダーティブロックの変更履歴を
 ログファイルに記録する場合には、log file syncイベントではなく、gcs log flush syncイベントを待機することが
 観察されることに注意しましょう。

上記のような状況の競争が発生した場合、Oracleは、ブロック処理の過程で競合が発生したと見なされます。

要求モードとbusyイベント

gc cr/current block busyイベントが発生する正確なタイミングは、ブロックリクエストがCRモードであるか、Currentモードであるかに応じて若干異なります。

リクエストノードのCRモード要求に対してホルダーノードがまだCommitが行われていない現在のブロックを転送する場合は、必ずCRブロック、すなわち変更前のイメージを送信する必要があります。問題は、ホルダーノードのバッファ・キャッシュにCRイメージが存在しない場合です。この場合、現在のブロックのコピー版であるCRコピーブロックを生成し、アンドゥイメージをディスクから読み取られた後、CRコピーブロックにロールバックを実行する一連の過程を経なければなりません。また、現在のブロックの、REDOフラッシュを実行します。このような一連の過程がホルダーノードのLMSプロセスに過度の負荷を与えるので、Oracleは不完全なイメージのCRブロックを要求ノードに送信します。不完全なCRブロックを送信されたリクエストノードが自らの完全なイメージのCRブロックを生成することになります。これをLight Weight Rule(軽量化の法則)と呼びます。 V$CR_BLOCK_SERVERビューを照会すると、完全一貫性のある読み取り操作中にLight Weight Ruleが何度も適用され確認することができます。

SQL> SELECT cr_requests, light_works FROM v$cr_block_server
 CR_REQUESTS	     LIGHT_WORKS
 ------------------     -----------------
   35331145		 3866363

Commitが行われていないダーティブロックのCRモード要求には、主にgc cr block2/3-way類のイベントをFixed-upイベントとして使用します。この過程で、REDOフラッシュ過程で遅延が発生した場合gc cr block busyイベントをFixed-upイベントとして使用します。

一方、Commitが行われたダーティブロックのCurrentモードの要求が発生した場合、すぐにロックダウングレードが発生します。この場合、要請ノードは、一般的にgc current block2/3-way類のイベントをFixed-upイベントとして使用し、万一ホルダーノードの、REDOフラッシュ過程で遅延が発生した場合gc current block busyイベントをFixed-upイベントに使用します。

パラメータと待機時間

待機パラメータ

gc cr/ current block busyイベントなどFixed-upイベントは、P1、P2、P3の値が別途付与されず、Placeholderイベント(ここではgc cr requestイベント)と同じ値を持つものと解釈すればよいのです。

 

待機時間

Check Point & Solution

 

gc cr block busy解消案

gc cr block busyイベントの待機を解消するための方法は次のとおりです。

・LGWRプロセスのパフォーマンスを最大化します。REDOログが配置され、デバイスを最適に構成します。
 LGWRプロセスのCPU優先度を高めることも良い方法になります。
・SQLチューニングを介して、読み取り操作と変更が同じブロックにアクセスする場合の数を減らします。
・バッファ・キャッシュのチューニングを介してメモリに読み込んだブロックがキャッシュから押し出
 される場合の数を減らします。
・ブロック分散手法(パーティション化、リバースキーインデックス、シーケンスのキャッシュサイズ)
 を用いてホットブロックが発生する確率を減らします。

gc cr block busyイベント待機は、ブロックの競合によって発生するため、インターコネクトの性能とは無関係に発生することがあることに注意しなければなりません。つまり、ブロックを送信する過程で遅延が発生するのではなく、ホルダーノードがブロック転送を準備する過程で遅延が発生するのです。したがって、ブロックの競合を減らすか、または、ブロックの競合過程で発生する、REDOフラッシュを最適化することがチューニング方法になります。もちろん、インターコネクトの性能が低い場合は待機回収に比べて待機時間は増えることができます。

簡単なテストでは、gc cr block busyイベント待ちとブロック変更との関係を確認することができます。

 - ノード2がマスターノードであるrac_testテーブル。
 - ノード2でrac_testテーブルに対してUpdateを実行した後Commitを実行しません。
SQL#2> UPDATE rac_test SET id = 3;

 - ノード1からrac_testテーブルをSelect。ノード2で変更されたブロックを読み込みます。
SQL#1> SELECT * FROM rac_test;
SQL#1> /
... (同じクエリを複数回実行)
 - 上記のクエリに対してSQL Traceを実行した結果は以下の通りです。
 - ホルダーノードでの、REDOフラッシュによって遅延が発生し、これにより、要求ノードは、
  gc cr block busyイベントを待機することを確認することができます。
 - ただし、のREDOフラッシュ過程は非常に軽い面gc cr block busyイベントではなく、
  gc cr block 2/3-way類のイベントに観察されます。

select * from rac_test
WAIT#2:nam = 'SQL * Net message to client」ela = 3 p1 = 16508 p2 = 1 p3 = 0
WAIT#2:nam = 'gc cr block busy」ela = 68615 p1 = 14 p2 = 10344 p3 = 1
WAIT#2:nam = 'SQL * Net message from client」ela = 313 p1 = 16508 p2 = 1 p3 = 0
WAIT#2:nam = 'SQL * Net message to client」ela = 2 p1 = 16508 p2 = 1 p3 = 0
WAIT#2:nam = 'SQL * Net message from client」ela = 410 p1 = 16508 p2 = 1 p3 = 0