Lock Jp
概要      Oracle RDBMSで使用されているロッキング・メカニズム概要(エンキュー、ラッチ、その他)
内容:
 
[概要]
Oracle RDBMS内では、複数のプロセスやセッションが共有するリソースを保護するために
何種類かのロッキング・メカニズムを使用しています。この文書では、それぞれの概要を
解説します。
 
[詳細]
シングル・インスタンスのOracle RDBMS内で使用されているロッキング・メカニズムには、
次のような種類があります。
 
- エンキュー
  共有、排他等のロック・モードを持つことができ、ロックが獲得できない場合はキューイング
  され、先に待機を開始したセッションから先にロック獲得の権利を得るFIFO(First In 
  First Out)型のロックです。
  エンキュー自体は、Oracle RDBMS内の汎用的な排他制御のためのサービスとして実装されて
  おり、それが様々な局面で利用されています。例えば、DML表ロックや行ロック、リカバリ
  時にデータ・ファイルを保護するロック、制御ファイルの同時更新を防ぐためのロック、
  順序オブジェクトでの発番を保護するロック等はすべてエンキューで実装されています。
  エンキューは、アルファベット2文字のTYPEと、数値であるID1ID2という3つの要素の
  組み合わせで識別され、その識別子ごとに保護するリソースが異なります。ID1ID2が
  何を意味するかはTYPEによって異なります。表ロックであればオブジェクトIDが含まれて
  いたり、ファイルに対するロックであればファイル番号が含まれていたりします。
  エンキューが獲得できない場合の待機イベントは、9iまでのリリースでは'enqueue'が
  使用されていました。
  V$SESSION_WAITでは、P1が待機しているエンキューのTYPEMODE(上位/下位2バイトずつ
  使用しているので、P1RAWで参照したがわかりやすい)P2ID1P3ID2に対応して
  います。
 
    9iまでのリリースでのエンキュー待機例:
 
       SQL> select SID, EVENT, P1RAW, P2, P3 from V$SESSION_WAIT
         2  where EVENT = 'enqueue';
 
       SID EVENT      P1RAW          P2       P3
       --- ---------- -------- -------- --------
         9 enqueue    54580004   131078     9587
 
           -> SID=9のセッションがTYPE=TX(ASCIIコードの0x5458)ID1=131078ID2=9587のエンキューをMODE=4(SHARE)で獲得しようとして待機しています。
 
  10.1以降のリリースでは、待機しているエンキューのタイプごとに待機イベントが用意され、
  一部のタイプでは待機理由によってさらに複数の待機イベントが使い分けられます。
 
    10gでのエンキュー待機例:
 
       SQL> select SID, EVENT, P1RAW, P2, P3 from V$SESSION
         2  where EVENT like 'enq%';
 
       SID EVENT                          P1RAW            P2         P3
       --- ------------------------------ -------- ---------- ----------
       147 enq: TX - row lock contention  54580006     524308       2687
 
           -> SID=147のセッションがTYPE=TXID1=524308ID2=2687のエンキューを
              MODE=6(EXCLUSIVE)で獲得しようとして待機しています。
              TYPE=TXのエンキューをMODE=6で待機するのは行ロック競合によるものです。
 
  注:行ロック解放を複数のトランザクションが待機している場合は、最初にロックを獲得
      したトランザクションの終了によってロックの所有者が変わると待機するエンキュー
      そのものが変更になり、この時に2番目以降に待機していたセッションの待機順序が
      そのまま移行されない可能性があります(KROWN:35712を参照)。
 
- ラッチ
  基本的にモードは排他のみ(一部例外あり)の内部ロックです。リリース8.1までは
  エンキューのようにキューイングの仕組みを持たず、待機する場合はそれぞれのプロセスが
  タイムアウトを繰り返しながらリトライするので、先に待ち始めたプロセスが先にロック
  獲得の権利を得るとは限りません。リリース9.0以降は、ラッチの場合もFIFO形式で獲得
  が行われるように変更されています。
  エンキューに比べると仕組みが単純で低コストなロッキング・メカニズムとして実装されて
  います。
  共有プール上でのメモリの割り当てや解放、バッファ・キャッシュ上でのバッファの探索、
  ライブラリ・キャッシュ上でのオブジェクトの探索、セッションの開始、チェックポイント
  の開始、ログ・バッファの割り当て等、多くの処理がラッチによって保護されています。
  ラッチが獲得できない場合の待機イベントは、9iまでのリリースでは'latch free'が
  使用されていました。
  V$SESSION_WAITでは、P1がラッチのアドレス、P2がラッチ番号に対応しています。
 
    9iまでのリリースでのラッチ待機例:
 
       SQL> select SID, EVENT, P1RAW, P2 from V$SESSION_WAIT
         2  where EVENT = 'latch free';
 
       SID EVENT      P1RAW          P2
       --- ---------- -------- --------
        12 latch free 20015CA4      154
 
           -> SID=12のセッションが、ADDR=20015CA4LATCH#=154のラッチを獲得しよう
              として待機しています。V$LATCHNAMEを参照すれば、該当のラッチが何で
              あるかがわかります。
 
       SQL> select NAME from V$LATCHNAME where LATCH#=154;
 
       NAME
       ----------------
       shared pool
 
  10.1以降のリリースでは、一部のラッチでは待機しているラッチの種類ごとに待機イベント
  が用意されています。
 
    10gでのエンキュー待機例:
 
       SQL> select SID, EVENT, P1RAW, P2 from V$SESSION
         2  where EVENT = 'latch free';
 
       SID EVENT              P1RAW          P2
       --- ------------------ -------- --------
       148 latch: shared pool 20097FAC      213
 
           -> SID=148のセッションが、shared poolラッチを獲得しようとして待機しています。
 
  ただしラッチは種類が多いので、ほとんどのラッチは10.1以降のリリースでも'latch free'
  という共通の待機イベントを使用します。
 
- 行キャッシュ・ロック
  共有プール内のディクショナリ情報をキャッシュする行キャッシュ(Row Cache)を保護する
  ロックです。
  行キャッシュ・ロックが獲得できない場合は、'row cache lock'という待機イベントで
  待機します。
  V$SESSION_WAIT(10.1以降はV$SESSIONで可)では、P1がキャッシュID(V$ROWCACHE.CACHE#)、
  P2が獲得モード、P3が要求モードに対応しています。
 
- ライブラリ・キャッシュ・ロックおよびライブラリ・キャッシュ・ピン
  共有プール内の共有カーソルやDBオブジェクトの定義情報をキャッシュするライブラリ・
  キャッシュ(library cache)を保護するロックです。ライブラリ・キャッシュにキャッシュ
  されるオブジェクトは何種類かのメモリ断片で構成される複雑な構造をしているため、
  どの部分を保護するかによって、「ロック」と「ピン」の2種類があります。
  ライブラリ・キャッシュ・ロックが獲得できない場合は、'library cache lock'という
  待機イベントで、ライブラリ・キャッシュ・ピンが獲得できない場合は、'library cache 
  pin'という待機イベントで待機します。V$SESSION_WAIT(V$SESSION)では、P1がライブラリ・
  キャッシュ・オブジェクト・ハンドルのアドレス、P2がロックまたはピンのアドレスに対応
  し、P310*要求モード + NAMESPACE# の値になります。
 
- バッファ・ピン
  バッファ・キャッシュにキャッシュされているブロックが同時に更新されたり、読み込みが
  不完全な状態で参照されたりすることを防ぐためのロックです。
  バッファ・ピンが獲得できない場合は、'buffer busy waits'または'write complete 
  waits'という待機イベントで待機します。V$SESSION_WAIT(V$SESSION)では、
  P1が絶対ファイル番号、P2がブロック番号、P3は待機理由を表すコード(-9.2)または
  ブロック・クラス(10.1-)に対応します。
  (ブロック・クラスについては参照情報の文書番62357を参照してください。)
 
上記以外にも、RAC環境では複数インスタンス間での排他制御を行うためのRAC固有の
ロッキング・メカニズムが使用されます。

キーワード:

ロック エンキュー ラッチ 行キャッシュ ライブラリ・キャッシュ バッファ・キャッシュ ピン

Reference: KROWN-54593
KRWON-46973: 待機イベント"enqueue"について  
KRWON-35712: ロックの獲得が、要求した順番通りになりません。
KRWON-45696: ラッチの実装とラッチ競合の原因
KRWON-70366: ラッチの待機方法について
KRWON-62357: V$BHビューのCLASS#列の値、およびV$WAITSTATのCLASS列について
KROWN-71034:

page_revision: 3, last_edited: 1251112497|%e %b %Y, %H:%M %Z (%O ago)