Buffer busy waitsイベント
プロセスがSGAのbufferにアクセスする必要がある場合、次の手順に従います.
1.cache buffers chains latchを取得し、必要なbuffer headerが見つかるまでそのbuffer chainを巡回する
2.buffer header上で共有モードまたは独占モードのbuffer pinまたはbuffer lockを取得する必要がある操作タイプ(読み取りまたは書き込み)
3.プロセスがbuffer header pinを取得すると、取得したcache buffers chains latchが解放され、buffer blockの操作が実行されます.
4.プロセスがbuffer header pinを取得できない場合、buffer busy waitsイベントで待機します.
プロセスがbuffer header pinを取得できないのは、データの一貫性を保証するために、同じ時刻に1つのblockが1つのプロセスpinによってしかアクセスできないため、1つのプロセスがbuffer cacheのうちの1つの他のプロセスで使用されるblockにアクセスする必要がある場合、このプロセスはそのblockに対するbuffer busy waitsイベントを発生する.
Oracle 9 i現在、buffer busy waitsイベントのp 1,p 2,p 3の3つのパラメータはそれぞれfile#,block#,idであり、待機中のbuffer blockが存在するファイル番号、ブロック番号、具体的な待機原因番号をそれぞれ表し、Oracle 10 gになると、前の2つのパラメータは変化せず、3番目のパラメータはブロックタイプ番号になります.これはv$event_nameビューで検証:
buffer busy waitsイベントを診断するときに、次の情報を取得すると便利です.
1.buffer busy waitsイベントを生成する待機理由番号を取得します.これは、イベントのp 3パラメータ値をクエリーすることによって取得できます.
2.このイベントを生成するSQL文を取得します.次のクエリで取得できます.
select sql_text from v$sql t1,v$session t2,v$session_wait t3
where t1.address=t2.sql_address and t1.hash_value=t2.sql_hash_value
and t2.sid=t3.sid and t3.event='buffer busy waits';
3.待機中のブロックのタイプと、存在するsegmentを取得します.次のクエリで取得できます.
クエリーの第1部:待機するブロックタイプがsegmentヘッダである場合、buffer busy waitsイベントのp 1およびp 2パラメータをdba_に直接取得できます.segmentsビューでheader_を一致させるfileとheader_blockフィールドでは、待機中のsegment名とsegmentタイプを見つけて調整できます.
クエリーの第2部:待機するブロックタイプがfreelist groupsの場合、dba_segmentsビューで対応するsegment名とsegmentタイプを見つけます.ここでのパラメータp 2が表すfreelist groupsの位置はsegmentのheader_であることに注意してください.block+1からheader_block+freelist groupsグループ数の間、freelist groupsグループ数が1より大きい
クエリーの第3部:待機するブロックタイプが通常のデータブロックである場合、p 1、p 2パラメータ、dba_extentsは共同クエリーを行いblockが存在するsegment名とsegmentタイプを得る
異なる待機ブロックタイプについては、次のような処理を行います.
1.data segment header:
プロセスの頻繁なアクセスdata segmentヘッダには、通常、process freelists情報の取得または変更、高水位タグの拡張の2つの理由があります.1つ目の場合、プロセスがprocess freelists情報に頻繁にアクセスすることで、freelist競合が発生し、対応するsegmentオブジェクトのストレージパラメータfreelistまたはfreelist groupsを大きくすることができます.データブロックが頻繁にfreelistに出入りするため、プロセスが頻繁にfreelistを変更する場合、pctfree値とpctused値に大きな差を設定することで、データブロックが頻繁にfreelistに出入りすることを回避できます.第2のケースでは、このsegment空間の消費が速いため、設定されたnext extentが小さすぎるため、高水位マーカーが頻繁に拡張され、segmentオブジェクトの記憶パラメータnext extentを大きくするか、表空間を作成するときにextent size uniformを直接設定することが解決策です.
2.data block:
1つまたは複数のデータ・ブロックが同時に読み書きされ、ホットスポット・ブロックとなり、この問題を解決するには、次のような方法があります.
(1)プログラムの同時性を低減し、プログラムでparallelクエリーを使用した場合、parallel degreeを低減し、複数のparallel slaveが同じデータオブジェクトに同時にアクセスして待機低減性能を形成しないようにする
(2)アプリケーションが少ないブロックを読み取れば必要なデータを取得できるように調整し、buffer getsとphysical readsを減らす
(3)同じブロックのレコード数を減らして、レコードをより多くのデータブロックに分散させることは、segmentオブジェクトのpctfree値を調整することができ、segmentをblock sizeの小さいテーブル空間に再構築することができ、alter table minimize records_を使用することもできる.per_block文はブロックあたりのレコード数を減らす
(4)ホットスポットブロックオブジェクトが自己増加idフィールドのようなインデックスである場合、インデックスを反転インデックスに変換し、データ分布を分散し、ホットスポットブロックを分散することができる
3.undo segment header:
undo segment header競合は、システム内でundo segmentが不足しているため、十分なundo segmentを追加する必要があります.undo segmentの管理方法によって、手動管理モードであればrollback_を変更する必要があります.segments初期化パラメータはrollback segmentを増加させ、自動管理モードであればtransactions_を減少させることができる.per_rollback_segment初期化パラメータの値によりoracleがrollback segmentの数を自動的に増加
4.undo block:
undo block競合は、アプリケーションにデータの読み取りと書き込みが同時に行われるため、読み取りプロセスはundo segmentで一貫性のあるデータを得る必要があります.解決策は、アプリケーションがデータを修正し、大量のクエリーデータを取得する時間をずらすことです.
まとめ:buffer busy waitsイベントはoracle待機イベントの中で比較的複雑な1つであり、その形成原因は多く、p 3パラメータに基づいてOracleが提供した原因コードテーブルに対して相応の診断を行う必要があり、10 g以降は待機するblockタイプに基づいて待機時間を引き起こす具体的なSQLを結合して分析し、相応の調整措置をとる必要がある.
1.cache buffers chains latchを取得し、必要なbuffer headerが見つかるまでそのbuffer chainを巡回する
2.buffer header上で共有モードまたは独占モードのbuffer pinまたはbuffer lockを取得する必要がある操作タイプ(読み取りまたは書き込み)
3.プロセスがbuffer header pinを取得すると、取得したcache buffers chains latchが解放され、buffer blockの操作が実行されます.
4.プロセスがbuffer header pinを取得できない場合、buffer busy waitsイベントで待機します.
プロセスがbuffer header pinを取得できないのは、データの一貫性を保証するために、同じ時刻に1つのblockが1つのプロセスpinによってしかアクセスできないため、1つのプロセスがbuffer cacheのうちの1つの他のプロセスで使用されるblockにアクセスする必要がある場合、このプロセスはそのblockに対するbuffer busy waitsイベントを発生する.
Oracle 9 i現在、buffer busy waitsイベントのp 1,p 2,p 3の3つのパラメータはそれぞれfile#,block#,idであり、待機中のbuffer blockが存在するファイル番号、ブロック番号、具体的な待機原因番号をそれぞれ表し、Oracle 10 gになると、前の2つのパラメータは変化せず、3番目のパラメータはブロックタイプ番号になります.これはv$event_nameビューで検証:
PHP code:
Oracle 9i
SQL> select parameter1,parameter2,parameter3 from v$event_name where name='buffer busy waits';
PARAMETER1 PARAMETER2 PARAMETER3
------------------------ ------------------------ ------------------------
file# block# id
Oracle 10g
PARAMETER1 PARAMETER2 PARAMETER3
------------------------ ------------------------ ------------------------
file# block# class#
buffer busy waitsイベントを診断するときに、次の情報を取得すると便利です.
1.buffer busy waitsイベントを生成する待機理由番号を取得します.これは、イベントのp 3パラメータ値をクエリーすることによって取得できます.
2.このイベントを生成するSQL文を取得します.次のクエリで取得できます.
select sql_text from v$sql t1,v$session t2,v$session_wait t3
where t1.address=t2.sql_address and t1.hash_value=t2.sql_hash_value
and t2.sid=t3.sid and t3.event='buffer busy waits';
3.待機中のブロックのタイプと、存在するsegmentを取得します.次のクエリで取得できます.
PHP code:
select 'Segment Header' class,a.segment_type,a.segment_name,a.partition_name from dba_segments a,v$session_wait b
where a.header_file=b.p1 and a.header_block=b.p2 and b.event='buffer busy waits'
union
select 'Freelist Groups' class,a.segment_type,a.segment_name,a.partition_name from dba_segments a,v$session_wait b
where a.header_file=b.p1 and b.p2 between a.header_block+1 and (a.header_block+a.freelist_groups) and a.freelist_groups>1 and b.event='buffer busy waits'
union
select a.segment_type||' block' class,a.segment_type,a.segment_name,a.partition_name from dba_extents a,v$session_wait b
where a.file_id=b.p1 and b.p2 between a.block_id and a.block_id+a.blocks-1 and b.event='buffer busy waits' and not exists(select 1 from dba_segments where
header_file=b.p1 and header_block= b.p2);
クエリーの第1部:待機するブロックタイプがsegmentヘッダである場合、buffer busy waitsイベントのp 1およびp 2パラメータをdba_に直接取得できます.segmentsビューでheader_を一致させるfileとheader_blockフィールドでは、待機中のsegment名とsegmentタイプを見つけて調整できます.
クエリーの第2部:待機するブロックタイプがfreelist groupsの場合、dba_segmentsビューで対応するsegment名とsegmentタイプを見つけます.ここでのパラメータp 2が表すfreelist groupsの位置はsegmentのheader_であることに注意してください.block+1からheader_block+freelist groupsグループ数の間、freelist groupsグループ数が1より大きい
クエリーの第3部:待機するブロックタイプが通常のデータブロックである場合、p 1、p 2パラメータ、dba_extentsは共同クエリーを行いblockが存在するsegment名とsegmentタイプを得る
異なる待機ブロックタイプについては、次のような処理を行います.
1.data segment header:
プロセスの頻繁なアクセスdata segmentヘッダには、通常、process freelists情報の取得または変更、高水位タグの拡張の2つの理由があります.1つ目の場合、プロセスがprocess freelists情報に頻繁にアクセスすることで、freelist競合が発生し、対応するsegmentオブジェクトのストレージパラメータfreelistまたはfreelist groupsを大きくすることができます.データブロックが頻繁にfreelistに出入りするため、プロセスが頻繁にfreelistを変更する場合、pctfree値とpctused値に大きな差を設定することで、データブロックが頻繁にfreelistに出入りすることを回避できます.第2のケースでは、このsegment空間の消費が速いため、設定されたnext extentが小さすぎるため、高水位マーカーが頻繁に拡張され、segmentオブジェクトの記憶パラメータnext extentを大きくするか、表空間を作成するときにextent size uniformを直接設定することが解決策です.
2.data block:
1つまたは複数のデータ・ブロックが同時に読み書きされ、ホットスポット・ブロックとなり、この問題を解決するには、次のような方法があります.
(1)プログラムの同時性を低減し、プログラムでparallelクエリーを使用した場合、parallel degreeを低減し、複数のparallel slaveが同じデータオブジェクトに同時にアクセスして待機低減性能を形成しないようにする
(2)アプリケーションが少ないブロックを読み取れば必要なデータを取得できるように調整し、buffer getsとphysical readsを減らす
(3)同じブロックのレコード数を減らして、レコードをより多くのデータブロックに分散させることは、segmentオブジェクトのpctfree値を調整することができ、segmentをblock sizeの小さいテーブル空間に再構築することができ、alter table minimize records_を使用することもできる.per_block文はブロックあたりのレコード数を減らす
(4)ホットスポットブロックオブジェクトが自己増加idフィールドのようなインデックスである場合、インデックスを反転インデックスに変換し、データ分布を分散し、ホットスポットブロックを分散することができる
3.undo segment header:
undo segment header競合は、システム内でundo segmentが不足しているため、十分なundo segmentを追加する必要があります.undo segmentの管理方法によって、手動管理モードであればrollback_を変更する必要があります.segments初期化パラメータはrollback segmentを増加させ、自動管理モードであればtransactions_を減少させることができる.per_rollback_segment初期化パラメータの値によりoracleがrollback segmentの数を自動的に増加
4.undo block:
undo block競合は、アプリケーションにデータの読み取りと書き込みが同時に行われるため、読み取りプロセスはundo segmentで一貫性のあるデータを得る必要があります.解決策は、アプリケーションがデータを修正し、大量のクエリーデータを取得する時間をずらすことです.
まとめ:buffer busy waitsイベントはoracle待機イベントの中で比較的複雑な1つであり、その形成原因は多く、p 3パラメータに基づいてOracleが提供した原因コードテーブルに対して相応の診断を行う必要があり、10 g以降は待機するblockタイプに基づいて待機時間を引き起こす具体的なSQLを結合して分析し、相応の調整措置をとる必要がある.