buffer cache與相關的latch等待事件

n-lauren發表於2013-02-26
buffer cache與相關的latch等待事件

1.buffer cache
2.latch:cache buffers lru chain
3.latch:cache buffers chains


1.buffer cache

我的理解:
buffer cache理解成4塊結構: 三個列表+1個pool
三個列表指:
    lru                        (最近最少使用列表)
    dirty list (checkpoing queue)
    hast bucket        (與latch:cache buffer chain相關)

一個pool指:
   buffer pool = db_cache_size / db_block_size

buffer pool:
記憶體中,資料存放的位置,每個pool的大小就是db_block_size大小.
比如,db_cache_size=800M,db_cache_size=8192,那麼,buffer cache中包含的buffer pool 就有102400個(800*1024*1024/8192).

lru:
最近最少使用列表,一個順序的清單,最上面為:MRU端(最常使用的物件),最下面為:LRU端(最不常用的物件)
在資料庫初使化時,所有的buffer都被hash到LRU列表上管理;
當要從資料檔案中讀取資料時,首先要在LRU列表上查詢free buffer,找到後才讀取到buffer pool(即buffer cache)中.

dirty list:
髒資料列表,指向記憶體中需要寫入資料檔案的buffer pool的地址

hash bucket:
對於buffer pool,如果都通過一種結構管理,像從前面102400個pool中如果要找一個pool的話,效能會很低下.為了提高效率,oracle引入了 bucket結構,oracle將所有的buffer通過hash演算法將buffer存放到不同的bucket上,使用者需要定位buffer時,只用到 bucket中查詢少量的buffer就可以找到.這樣就提高了效率.


buffer cache的原理:
這個原理至關重要.

當一個Server程式需要讀取資料到buffer cache中時:

1).首先要判斷該資料是否存在於buffer中,如果存在,且可用.則獲取資料,再根據LRU演算法在LRU列表上移動該block;

2).如果資料不存在於buffer中,Server程式就要掃描lru列表,查詢可用的buffer空間(free buffer)以放資料到buffer中,
在掃描lru list的過程中,如果碰到已經被修改過的buffer,就將它移動到dirty list(checkpoint queue)上(由於增量檢查點的引入,DBWR程式也會主動掃描一定比例的LRU list,將發現的髒資料塊移動到dirty lis);
如果dirty list(checkpoint queue)達到了閾值,Server程式就會通知DBWn程式寫出髒資料到資料檔案(DBWR程式寫的一個觸發條件);
如果Server程式掃描lru列表到一個閾值還沒有找到足夠的free buffer,這時,就停止對lru的掃描轉而通知DBWR寫出髒資料,釋放記憶體空間;這時,程式處於free buffer wait等待.

3).找到足夠的buffer之後,Server程式就可以將資料從資料檔案讀入到buffer cache中;

4).如果讀取的block不滿足"一致性"需求,則Server程式就需要通過當前block的版本從回滾段中讀取該block的"一致性"映象返回給使用者(consistent gets).



2.latch:cache buffers lru chain

當使用者讀取資料到buffer cache中,或buffer cache根據LRU演算法進行管理時,就不可避免的要掃描LRU列表以獲取free buffer或更改buffer狀態.
buffer cache為眾多併發程式提供併發訪問,所以在搜尋的過程中,必須獲取latch鎖定記憶體結構,以防止併發訪問對記憶體中的資料造成損壞.
這個用於鎖定LRU的latch就是cache buffers lru chain.

cache buffers lru chain鎖存器的預設數量:
DB_WRITER_PROCESSES <= 4        鎖存器數= 4 * cpu數
DB_WRITER_PROCESSES > 4        鎖存器數= db_writer_processes * cpu數
可以通過初始化引數_db_block_lru_latches來向上調整cache buffers lru chain鎖存器的數量(不建議這麼做,除非在oracle support的建議下)

如果這個latch競爭激烈:
(1) 適當增大buffer cache,這樣可以減少讀資料到buffer cache,減少掃描lru列表的次數

(2) 適當增加lru latch數量,修改_db_block_lru_latches引數.不建議這麼做.

(3) 使用多緩衝池技術


3.latch:cache buffers chains

引起cache buffers chains爭用的原因一:低效率的SQL語句

    多個併發低效的SQL語句同時執行,都設法獲得相同的資料集,就造成cache buffers chains的爭用.
    調整高buffer_gets的SQL語句可以緩解這類問題.(較小的邏輯讀意味著較少的latch get操作,從而減少鎖存器爭用並改善效能。)

引起cache buffers chains爭用的原因二:熱點塊(最常見原因)
    判斷是不是熱塊問題的常用方法檢查latch free事件的p1raw引數值,如果p1raw是相同的鎖存器地址,則表明是熱塊問題.

    select sid,event,p1raw,p2,p3,seconds_in_wait,wait_time,state
    from v$session_wait
    where event = 'latch free';


    如果要確定具體的熱點塊,就要查詢v$latch_children,x$bh,dba_extents,根據子latch的資訊確認熱點塊.
    v$latch_children.addr 與x$bh.hladdr相關聯,可以確認子latch相關的塊.
    再根據x$bh.dbarfil與dba_extents.relative_fno和x$bh.dbablk與dba_extents.block_id&&block_id+blocks關聯,查到具體物件.


1> 檢視cache buffers chains子latch情況:

SQL> select * from
(select addr,child#,gets,misses,sleeps,immediate_gets igets,immediate_misses imisses,spin_gets
         from v$latch_children
        where name = 'cache buffers chains'
order by sleeps desc
)
where rownum<11;


ADDR         CHILD#       GETS     MISSES     SLEEPS      IGETS    IMISSES SPIN_GETS
-------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
69B625BC        739    1056438         65         41        645          0         46
69A821BC          3    1115506         54         39        711          0         34
69B0A9BC        451    1476125         96         30        573          0         83
69A83EFC          9     207227        833         20        800          0        823
69AA573C        119     167852        635         14        592          0        628
69AB2DBC        163     860553         22         14        670          0         15
69B8C19C        876    1283643       1125         12        224          0       1118
69B03E7C        429     315851         53         11        413          0         47
69B1C47C        509     590733         18         11        689          0         14
69BADEBC        987     223777        208         11        529          0        201

2> 聯合x$bh檢視查出相關塊資訊

SQL> select b.addr,a.tch,a.ts#,a.dbarfil,a.dbablk,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;


ADDR            TCH        TS#    DBARFIL     DBABLK       GETS     MISSES     SLEEPS
-------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
69BB451C      17729          6          5    1277992     548061          0          0
69B92CDC      17729          6          5    1277991     581254          0          0
69B7149C      17729          6          5    1277990     534335          0          0
69B4FC5C      17729          6          5    1277989     534914          0          0
69B2E41C      17728          6          5    1277988    1087533          1          0
69B0CBDC      17726          6          5    1277987     538605          0          0


3> 聯合dba_extents查出具體的資料物件

select distinct owner,segment_name,segment_type
from dba_extents a,
     (select * from (select addr,tch,ts#,file#,dbarfil,dbablk from x$bh order by tch desc)
       where rownum<11
     ) b
where a.relative_fno = b.dbarfil
and   a.block_id <= b.dbablk
and   a.block_id + blocks > b.dbablk;


4> 聯合v$sqltext或v$sqlarea找出相關的SQL語句

select /*+ rule */ hash_value,sql_text
from v$sqltext
where (hash_value,address) in
      (select a.hash_value,a.address
         from v$sqltext a,
              (select distinct a.owner,a.segment_name,a.segment_type
                 from dba_extents a,
                      (select dbarfil,dbablk
                         from (select dbarfil,dbablk
                                 from x$bh
                               order by tch desc
                              )
                        where rownum<11
                      ) b
           

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

相關文章