ablog

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

第3回 Oracle8i Internal Services 1人読書会

いまいちまとまってないけど公開しちゃう。

読んだところ

3. Latches

    • Latches and Locks
    • Parent and Child Latches
    • Latch Gets
    • Advanced Latching Control
    • Reference

書かれていること

ラッチについて

要約

ラッチとは
  • ラッチは Oracle 固有の用語。OS の機能ではない。
  • Oracle が内部的に使っているロック機構。
  • SGA(共有メモリ)内の管理情報を同時に参照・変更しないようにするための仕組み。変更だけでなく参照も同時にできない。つまり、完全に直列化しないといけない処理の排他制御に使われる。
  • Oracle はSGA(共有メモリ)のデータをロックとラッチで守っていて、保護するデータの特性に合わせていずれか適した方を使っている。
  • OS のスピンロックに似ている。
特徴
  • シンプルな仕組みなので高速。
  • ラッチを獲得できるまで単純にループ(スピン)して定期的にラッチをチェックしながら待つ。ロックのようにキューイングされない。
  • ラッチ取得操作には TEST AND SET、LOAD AND CLEAR、COMPARE AND SWAP などの CPU 命令が使われるため、アトミック操作が保証され、かつ高速に処理される。
  • ロック操作はラッチで保護されている。以下は例。
    • cache buffer locks <-- cache buffers chains latches
    • row cache enqueue locks <-- row cache objects latches
  • ほとんどのSGA(共有メモリ)内のデータは1つのラッチで保護されるが、データのサイズが大きくて1つのラッチで保護できない場合は、1つの親ラッチ + 複数の子ラッチで保護される。
種類
  • 親ラッチ
    • 子ラッチを持つ
    • 子ラッチを持たない(solitary latch)
  • 子ラッチ
ラッチ待機中の動作
  • CPU数による挙動の違い
    • 単一CPU: スリープして再要求する。
    • 複数CPU: スピンして再要求する。許容回数を超えても獲得できない場合、スリープする。
  • スピン
    • スピンの許容回数は初期化パラメータ _SPIN_COUNT で設定できる。デフォルト値は単一CPUなら 1、複数CPUなら 2000。
    • 複数CPUの場合のみスピンする。ラッチを確保しているプロセス1が CPU1 で実行中の間、ラッチを取得したいプロセス2が CPU2 でスピンするというイメージ。
    • スリープよりスピンのほうが処理コストが低いためスピンする。スリープするとコンテキストスイッチが発生するので処理コストが高い。
  • スリープ
    • Timeout
      • 一定時間経過するとOSが起こしてくれるようアラームをセットしてからスリープする。
      • 最初は0.1秒スリープし、2回目以降は「前回スリープ時間 × 2」というアルゴリズムでスリープ時間が長くなっていく。
      • スリープ時間は初期化パラメータ _MAX_EXPONENTIAL_SLEEP(8iではデフォルトで2秒) の値より大きくならない。
      • ラッチを獲得しようとしているプロセスが既に他のラッチを獲得している場合は、初期化パラメータ _MAX_SLEEP_HOLDING_LATCH(8iではデフォルトで0.4秒) より大きくならない。
    • Latch wait posting
      • latch wait list というリストに自分を追加してからスリープする。
      • ラッチを獲得しているプロセスがラッチを解放する時に latch wait list をチェックしてスリープしているプロセスを起こす。
      • ラッチが解放され次第、待機しているプロセスがラッチを獲得できるが、latch wait list というデータ構造をメンテナンスするため処理コストが高い。
      • デフォルトでは、Latch wait posting を使うのは library cache latches と shared pool latches のみ。
待機方法
  • Willing-to-Wait Mode
    • 獲得できなかった場合、待機して再要求する。
  • No-Wait(Immediate) Mode
    • プロセスが複数のラッチを同時に保持したい場合、同じまたは下位レベルのラッチを取得する際に使用する。
    • 取得できなかった場合、上位レベルのラッチを解放してラッチの取得を再試行するか、エラーコードを返すか、他の処理を続行する。
クリーンアップ
  • PMON が3秒毎に異常終了したサーバプロセスがないかチェックし、存在する場合、ラッチクリーンアップを行った後にトランザクションロールバックを行う。
  • それ以外にもサーバプロセスが繰返しラッチの取得に失敗した場合、latch activity test を行い、0.5秒以上ラッチ上で活動がない場合、PMON にクリーンアップを指示する。
チューニング
  • 以下が最小になるようチューニングすると良いらしい。ただし、これをいじるのは最終手段。
_SPIN_COUNT * sleeps / misses 

など