ablog

不器用で落着きのない技術者のメモ

第2回 Oracle8i Internal Services 1人読書会

読んだところ

2. Waits

    • Semaphores
    • Wait Statistics
    • Reference

書かれていること

  • この本の3章以降を理解するために必要なこと。
  • Oracle の多数のプロセスはどのように協調動作しているか。
  • Oracle のプロセスの協調動作に関連する OS、Oracle の設定。
  • ボトルネックを探すときに見るべき情報。

要約

Oracle の多数のプロセスはどのように協調動作しているか
  • 主にセマフォを使っている。
  • 1プロセスにつき1つのセマフォを使う。
  • プロセスは以下の場合、セマフォを使って待機する。
    • 使いたいリソースを誰かが使っている。
    • 他のプロセスが処理中の前提タスクが終わっていない。
    • やることがない。
  • 待機中のプロセスへの完了通知はセマフォを使って連絡する。
  • プロセスの状態は、blocked、runnable、running の3種類ある。待機中は blocked、セマフォで通知がきてキューに入ると runnable になって、実行中は running になる。 runnable から running になるまでの期間を Scheduling Latencies という。このキューに入ったプロセスの実行順をスケジューリングアルゴリズムが調整する。スケジューリングアルゴリズムには種類をどれにするかで Oracle のパフォーマンスに影響するので注意が必要。
  • セマフォはOS の機能
Oracle のプロセスの協調動作に関連する OS、Oracle の設定
  • post-wait driver のほうが良いが、実装されているか否かは OS に依存する。詳しいことは各OS の Oracle インストレーション・ガイド参照。
    • とのことだが、現在の Oracle には post-wait driver 関連の初期化パラメータがなくなっているので、最近の Oracle では System V セマフォのみ使用可能ではないかと思う。
  • System V セマフォ パラメータの設定
SEMMSL >= 初期化パラメータPROCESSES(インスタンスが複数ある場合は、最大のものを採用)
SEMMNI >= OSとその他のソフトウェア用 + インスタンス数
SEMMNS = SEMMSL * SEMMNI
MAXUP >= SEMMNS <-- Dynix/ptx(sequent) とかいうOSにこんなカーネルパラメータがあったらしい
NPROC >= SEMMNS * 3 <-- システム全体のプロセスの最大数
  • OSのスケジューリングアルゴリズム
    1. 優先度を下げないスケジューリングアルゴリズムを使う
    2. 1. が使えない場合は、プロセスの優先度を固定する
    3. 2. が使えない場合は、主なバックグラウンドプロセスの優先度を上げる
  • Oracle の初期化パラメータ
    • TIMED_STATISTICS: TRUE にする。そうしないと待機時間が記録されない。
    • _USE_VECTOR_POSTS: 1回のオペレーションで複数のプロセスを待機させることができる。
--手元の Oracle10gR2(10.2.0.4.0) on CentOS 5.3 で確認してみた。デフォルトで TRUE になるみたい。
SQL> select ksppinm name, ksppstvl value from x$ksppi join x$ksppcv using (indx) where ksppinm = '_use_vector_post';

NAME                 VALUE
-------------------- --------------------
_use_vector_post     TRUE
ボトルネックの探し方
  • 全体から詳細に徐々にスコープを絞っていく。
    • V$SYSTEM_EVENT でどの待機イベントに時間がかかってるか見て、V$SESSION_EVENT でどのセッションで時間がかかってるか見て、V$SESSION_WAIT でどのリソース(ラッチ、データブロック、エンキュー・ロックなど)で時間がかかっているか見れば原因をつきとめることができる。
    • V$SYSTEM_EVENT がインスタンス全体での統計、V$SESSION_EVENT がセッション毎の統計、V$SESSION_WAIT や SQLトレースは統計ではなく生データ。
    • つまり、インスタンスレベル→セッションレベル→生データとスコープを絞って行き、最終的に誰が悪いのかby name でつきとめる。
  • V$SYSTEM_EVENT
    • どの待機イベントに時間がかかっているかわかる。
    • 「TIME_WAITED / (TOTAL_WAITS - TOTAL_TIMEOUTS)」で平均待機時間を算出すると1回あたりの待ち時間が長い待機イベントがどれかわかる。これを logical wait と言う。例えば、buffer busy wait で1分待たされたとして、その間に3回タイムアウトした場合、論理的には1回の待機だが、TOTAL_WAITS を見ると4回待機したと記録される。
    • 待機イベントはアイドル待機イベント、ルーチン待機イベント、リソース待機イベントに分類できる。アイドル待機イベントはやることがなくて待機していただけなので見る必要なし。リソース待機イベントとルーチン待機イベントを見る必要がある。以下のSQLスクリプトを使うと楽ちん。
  • V$SESSION_EVENT
    • セッション単位でどの待機イベントの待ちが長いか見ることができる。
    • 遅いセッションがわかっていれば、セッションIDを指定してどの待機イベントで時間をくっているか調べることができる。
    • 待ち時間の長い待機イベントがわかっていれば、待機イベント名を指定してどのセッションがその待機イベントで待機しているか調べることができる。
  • V$SESSION_WAIT
    • どのリソースで待ちが発生しているか見ることができる。つまり、どこのだれが悪いのかがわかる。
    • 例えば、buffer busy waits で待機している場合、Wait Parameters(P1、P2、P3列)を見ればどのデータファイルのどのデータブロックを待っているかがわかる。
    • Wait Parameters(P1、P2、P3列)は待機イベントによって意味が異なる。Oracle社のドキュメントに説明があるが、わかりにくいのでこの本の3章以降で各待機イベントのWait Parameters(P1、P2、P3列)の意味を説明している。
    • V$SESSION_WAIT の情報は一瞬一瞬で変わる。あまり短いサイクルで V$SESSION_WAIT を select するとパフォーマンスに影響を及ぼす可能性がある。EVENT 10046 で SQLトレース を取ると負荷をかけずに V$SESSION_WAIT と同様の情報を取得できる。

*1:ちょっとよくわかってない