深入淺出cache buffer和shared pool記載02

dotaddjj發表於2011-12-09

當程式需要讀取資料到buffer cachecache buffer根據LRU演算法進行管理,就會掃描LRU list獲取可用buffer或更改buffer狀態,此時在搜尋過程中必須獲取latch,鎖定記憶體結構(latchoracle的一種序列鎖機制,保護共享記憶體結構),防止併發訪問順壞記憶體中的資料。

SQL> col name for a25

SQL> select addr,latch#,name,hash,gets,misses,immediate_gets,immediate_misses from v$latch where name='cache buffers lru chain';

ADDR LATCH# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES

-------- ---------- ------------------------- ---------- ---------- ---------- -------------- ----------------

03C43568 117 cache buffers lru chain 3559635447 118207 0 31831 0

Cache buffer lru chain latch存在多個子latch,其數量由隱含引數_db_block_lru_latches控制

查詢隱含引數的sql

SQL> col ksppdesc for a25

SQL> col ksppstvl for a25

SQL> Select ksppinm name, ksppdesc, ksppstvl

2 from x$ksppi a, x$ksppcv b

3 Where a.indx = b.indx

4 and a.inst_id = userenv('instance')

5 and b.inst_id = userenv('instance')

6 and ksppinm = '_db_block_lru_latches'

7 ;

NAME KSPPDESC KSPPSTVL

------------------------- ------------------------- -------------------------

_db_block_lru_latches number of lru latches 8

以上指令碼可以用於查詢oracle中所有的隱含引數的指令碼,只需要把後面的ksppinm值修改即可!

Select addr,latch#,child#,name,hash,gets,misses,immediate_gets,immediate_misses

from v$latch_children where name='cache buffers lru chain'

ADDR LATCH# CHILD# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES

-------- ---------- ---------- ------------------------- ---------- ---------- ---------- -------------- ----------------

2564E7AC 117 1 cache buffers lru chain 3559635447 12 0 0 0

2564EB5C 117 2 cache buffers lru chain 3559635447 12 0 0 0

------

8 rows selected

如果該latch競爭激烈,通常採取

1 增大buffer cache,增大快取命中率,減少了LRU list掃描機會

2 增加db_block_lru_latches隱含引數,將產生多個cache buffers lru chain的子latch,減少競爭,不過該隱含_db_block_lru_latches靜態引數一般是足夠的,建議在oracle support建議或瞭解深入情況下修改。

3 透過多快取池技術,db_recycle_cache_sizedb_keep_cache_size可以減少不希望的資料老化和全表掃描對於default池的衝擊,從而減少競爭!

使用者請求查詢相應資料會先檢視buffer cache中是否存在相應的buffer,那麼如何來確認是否存在相應buffer,如果直接遍歷buffer cache,那麼效能會相當低下!buffer cache的管理還存在hash bucketcache buffer chain資料結構。

Oracle把管理的所有buffer透過一個內部的hash演算法後,存放到不同的hash bucket中,每個hash bucket中都有一個cache buffer chain雙向連結串列將hash bucket內的buffer header資訊儲存進來,buffer cache透過hash bucket分割之後,眾多buffer就被分佈到一定數量bucket之中,使用者查詢資料時只需要先透過hash運算得到相應的hash值然後到相應的hash bucket中查詢cache buffer chainbuffer header來確定是否存在!

buffer hash存放的是資料塊的概要資訊,包括資料塊檔案號,塊地址,狀態等,判斷資料是否在buffer cache存在,只需要檢查buffer header即可確定,buffer header中存在只想具體buffer的指標!

這樣如果某個資料塊被獲取先要獲取這個資料塊所在的cache buffer chainlatch,如果此時有別的session也在獲取該latch,則其他session需要spin,如果spin次數超過_spin_count,也可以休眠sleep下然後再來競爭!

oracle 9I開始,對於cache buffer chain的只讀訪問,latch可以被共享,但是如果修改就需要獨享這個latch了!(latch由三種記憶體元素組成:pid(程式ID 記憶體地址和記憶體長度,latch用於儲存記憶體結構的完整性,對物件的訪問安全控制是鎖lock

由於buffer根據buffer header進行雜湊hash運算然後存放於hash bucket,那麼hash bucket數量一定程式決定了bucketbuffer多少,相應的hash bucket多點,那麼hash

Bucket內的buffer就會少點,那麼就能相應的減少cache buffer chainlatch競爭,不過更多的hash bucket則會需要更多的空間於管理成本!

Hash bucket的設定受隱含引數_db_block_hash_buckets的影響,對應每個bucket只存在一個chain,當使用者在buffer cache中搜尋資料塊時,需要搜尋相應的bucketcache buffer chain,此時需要獲取cache buffer chain latch,在oracle 8I之前,對於每個hash bucketoracle使用一個獨立的cache buffer hash latch維護,這樣_db_block_hash_latches的數量和bucket是一致的。在oracle8I開始,_db_block_hash_buckets數量較以前增加了8倍,而db_block_hash_latchs數量增加有限,由於增加了bucket而減少了每個bucket上的buffer數量,則每個latch可以完全管理多個buckets

上述的關於db_block_hash_bucketsdb_block_hash_latch同樣可以用上述的查詢隱含引數的指令碼檢視相應資訊!

熱點塊競爭:很多程式同時對相應的buffer所在的bucketcache buffer chain訪問,將產生cache buffer chain競爭,也就是所謂的熱點塊競爭!

x$bh資料字典表,也就是存放的buffer headers的資訊,buffer header中儲存buffer的資料塊的檔案號 塊地址,狀態等資訊,根據這些資訊結合dba_extents檢視,可以很容易找到buffer對應的物件資訊

其中的tch就是touch縮寫,表示一個buffer的訪問次數,buffer被訪問的次數越多,該buffer所在的bucket內的cache buffer chain競爭越激烈,可能會存在熱點塊競爭問題。

Addr 地址 TS# 表空間號 file# 資料檔案號 dbarfil 檔案號 dbablk 資料塊號

Tch 訪問次數

nxt_hashcache buffer chain內下一個buffer header編號

Prv_hashcache buffer chain內下一個buffer header

Nxt_repl:LRU上的下一個buffer

PRV-repl:LRU上的上一個buffer

HLADDR hash chain latch address可以和v$latch_child.addr關聯

查詢熱點塊所在的owner和物件 型別

select e.owner,e.segment_name,e.segment_type 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.relative_fno=b.dbarfil and e.block_id<=b.dbablk and e.block_id+e.blocks>b.dbablk

oracle 10g之前,資料庫的等待事件中,所有latch等到被歸入latch free等待事件,10g後,有些latch等待可能表現為單獨的等待事件。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25362835/viewspace-1056772/,如需轉載,請註明出處,否則將追究法律責任。

相關文章