buffer cacheについて

8096 ワード

参考文献

  • Oracle
  • の詳細な解析
  • v$latch
  • v$latch_children

  • 一、コンピュータプロセスアクセスデータ原理
    コンピュータプロセスがデータにアクセスする必要がある場合は、メモリから目的のデータがあるかどうかを優先し、メモリにない場合はハードディスク(HDD)からデータを読み出します.このような設計には、コンピュータがメモリ内のデータにアクセスする速度がハードディスク内のデータにアクセスする速度よりはるかに高いため、メモリ内の既存のキャッシュデータを利用することで、コンピュータの稼働効率を大幅に向上させることができる.
    二、buffer cacheに対するOracleの管理
    buffer cacheを中国語の辞書にたとえると、すべてのbufferは辞書の具体的な内容であり、buffer headerは辞書ディレクトリの字であり、buffer headerは対応するbufferのファイル番号、ブロックアドレス、状態などの情報を記録しており、buffer headerを通じて対応するbufferを見つけることができる.しかし、ある字の情報を検索しようとすると、すべての字を巡ってこの字を先に見つけることはできないので、bucketがあります.このbucketは辞書のピンイン検索または部首検索法であり、Oraclerはデータブロックアドレス(DBA)のハッシュ値を計算することによって、1つのbufferブロックがどのbucketに格納されるかを決定し、同じbucketのcacheがcache buffer chainを構成します.したがって、Oracleプロセスでデータにアクセスする必要がある場合は、アクセスするデータのブロックアドレスのハッシュ値を計算し、その値によって対応するbucketを見つけ、対応するbucketからデータのbuffer headerを検索し、最後にbuffer headerによってメモリにアクセスするデータを見つけます.ただし、アクセスするデータがメモリに存在せず、ディスクから読み込まれたデータを格納するのに十分なスペースがない場合は、LRUとLRUWチェーンテーブルを使用する必要があり、この2つのチェーンテーブルにもbufferのbuffer headerが記録されているが、異なることに、LRUチェーンテーブルには修正されていないbuffer情報が記録されており、LRUWには修正されたbuffer情報が記録されている.Oracleでは、まずLRUチェーンテーブルをスキャンし、変更されたbufferをLRUWチェーンテーブルに移動し、DBWRを移動してLRUWチェーンテーブルのデータをディスクに書き込み、bufferスペースを解放して新しいデータを読み込むことができます.
    三、Cache buffer LRU chain
    プロセスがbuffer cacheにデータを読み込む必要がある場合、LRUチェーンテーブルの更新がスキャンされ、buffer cacheのデータにアクセスすると、LRUアルゴリズムによってLRUチェーンテーブルも更新されます.複数のプロセスが同時にLRUチェーンテーブルを変更しないようにするには、LRUチェーンテーブルを更新するときに、LRUをロックするためのlatchがcache buffer lru chainであるlatchを取得する必要があります.cache buffer lru chain情報を表示するには、次の手順に従います.
    SET lines 2000 
    col name FOR a30
    
    SELECT addr,
           latch#,
           name,
           gets,
           misses,
           immediate_gets,
           immediate_misses
    FROM   v$latch
    WHERE  name = 'cache buffers lru chain';
    

    各子latchの使用状況を表示するには、次の手順に従います.
    SET lines 2000 col name FOR a20
    
    SELECT addr,
           child#,
           name,
           gets,
           misses,
           immediate_gets   igets,
           immediate_misses imisses
    FROM   v$latch_children
    WHERE  name = 'cache buffers lru chain';
    

    四、Cache buffer chain
    同じbucketのデータブロックはcache buffer chainに接続され、複数のプロセスが同じbucketのデータブロックにアクセスする必要がある場合、すべて読み取り専用であれば、このbucketのlatchを共有し、その中のデータブロックに共同アクセスすることができ、プロセスが書き込まれる必要がある場合は、bucketを独占するlatchが必要である.
    クエリーホットスポットブロック
    SELECT *
    FROM   (SELECT addr,
                   ts#,
                   file#,
                   dbarfil,
                   dbablk,
                   tch
            FROM   x$bh
            ORDER  BY tch DESC)
    WHERE  rownum < 11;
    

    ホットスポットブロックが属するオブジェクト情報のクエリー
    SET lines 2000 
    col owner FOR a20 
    col segment_name FOR a40
    
    SELECT e.owner,
           e.segment_name,
           e.segment_type,
           b.addr,
           b.ts#,
           b.file#,
           b.dbarfil,
           b.dbablk,
           b.tch
    FROM   dba_extents e,
           (SELECT *
            FROM   (SELECT addr,
                           ts#,
                           file#,
                           dbarfil,
                           dbablk,
                           tch
                    FROM   x$bh
                    ORDER  BY tch DESC)
            WHERE  rownum < 11) b
    WHERE  e.file_id = b.file#
           AND e.block_id <= b.dbablk
           AND e.block_id + e.blocks > b.dbablk;
    

    特定のlatch競合をホットスポットブロックに関連付ける
    SET lines 2000
    
    SELECT b.addr,
           a.ts#,
           a.dbarfil,
           a.dbablk,
           a.tch,
           b.gets,
           b.misses,
           b.sleeps
    FROM   (SELECT *
            FROM   (SELECT addr,
                           ts#,
                           file#,
                           dbarfil,
                           dbablk,
                           tch,
                           hladdr
                    FROM   x$bh
                    ORDER  BY tch DESC)
            WHERE  rownum < 11) a,
           (SELECT addr,
                   gets,
                   misses,
                   sleeps
            FROM   v$latch_children
            WHERE  name = 'cache buffers chains') b
    WHERE  a.hladdr = b.addr;
    

    特定のlatch競合とホットスポットブロックを特定のブロック情報に関連付ける
    SET lines 2000 
    col owner FOR a20 
    col segment_name FOR a60
    
    SELECT /*+ rule */ e.owner,
                       e.segment_name,
                       e.segment_type,
                       b.addr,
                       a.ts#,
                       a.dbarfil,
                       a.dbablk,
                       a.tch,
                       b.gets,
                       b.misses,
                       b.sleeps
    FROM   dba_extents e,
           (SELECT *
            FROM   (SELECT addr,
                           ts#,
                           file#,
                           dbarfil,
                           dbablk,
                           tch,
                           hladdr
                    FROM   x$bh
                    ORDER  BY tch DESC)
            WHERE  rownum < 11) a,
           (SELECT addr,
                   gets,
                   misses,
                   sleeps
            FROM   v$latch_children
            WHERE  name = 'cache buffers chains') b
    WHERE  a.hladdr = b.addr
           AND e.file_id = a.file#
           AND e.block_id <= a.dbablk
           AND e.block_id + e.blocks > a.dbablk;
    

    クエリはホットスポットブロック上の特定のsql文を実行する
    SET lines 2000 
    col owner FOR a20 
    col segment_name FOR a60
    
    SELECT /*+ rule */ hash_value,
                       sql_text
    FROM   v$sqltext
    WHERE  ( hash_value, address ) IN (SELECT s.hash_value,
                                              s.address
                                       FROM   v$sqltext s,
                                              (SELECT e.owner,
                                                      e.segment_name,
                                                      e.segment_type,
                                                      b.addr,
                                                      a.ts#,
                                                      a.dbarfil,
                                                      a.dbablk,
                                                      a.tch,
                                                      b.gets,
                                                      b.misses,
                                                      b.sleeps
                                               FROM   dba_extents e,
                                                      (SELECT *
                                                       FROM   (SELECT addr,
                                                                      ts#,
                                                                      file#,
                                                                      dbarfil,
                                                                      dbablk,
                                                                      tch,
                                                                      hladdr
                                                               FROM   x$bh
                                                               ORDER  BY tch DESC)
                                                       WHERE  rownum < 11) a,
                                                      (SELECT addr,
                                                              gets,
                                                              misses,
                                                              sleeps
                                                       FROM   v$latch_children
                                                       WHERE  name = 'cache buffers chains') b
                                               WHERE  a.hladdr = b.addr
                                                      AND e.file_id = a.file#
                                                      AND e.block_id <= a.dbablk
                                                      AND e.block_id + e.blocks > a.dbablk) abe
                                       WHERE  Upper(s.sql_text) LIKE '%'
                                                                     || abe.segment_name
                                                                     || '%'
                                              AND abe.segment_type = 'TABLE')
    ORDER  BY hash_value,
              address,
              piece;