buffer cacheについて
8096 ワード
参考文献
一、コンピュータプロセスアクセスデータ原理
コンピュータプロセスがデータにアクセスする必要がある場合は、メモリから目的のデータがあるかどうかを優先し、メモリにない場合はハードディスク(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;