天天看點

深入了解latch: cache buffers chains

事件背景:   

一個客戶的資料庫發生了當機事件,檢視了資料庫的awr報告,原來是由于出現大量的latch: cache buffers chains等待事件導緻系統消耗量大量的CPU,最終導緻系統hang住;

說明:   

要了解latch: cache buffers chains并解決這個問題,就需要深入的了解Buffer Cache及其原理。

1、Buffer Cache概述:   

Buffer Cache是SGA的一部分,Oracle利用Buffer Cache來管理data block,Buffer Cache的最終目的就是盡可能的減少磁盤I/O。Buffer Cache中主要有3大結構用來管理Buffer Cache:Hash Bucket、Hash Chain List、LRU List;   

Hash Bucket & Hash Chain List :Hash Bucket與Hash Chain List用來實作data block的快速定位。   

LRU List :挂載有指向具體的free buffer, pinned buffer以及還沒有被移動到 write list的dirty buffer 等資訊。所謂的free buffer就是指沒有包含任何資料的buffer,所謂的pinned buffer,就是指目前正在被通路的buffer。   

Write(Dirty)List :挂載有指向具體的 dirty block的資訊。所謂的dirty block,就是指在 buffer cache中被修改過但是還沒有被寫入到磁盤的block。

2、Hash Bucket的原理:   

如果所有的Buffer Cache中所有的Buffer都通過同一個結構管理,當需要确定某個Block在Buffer中是否存在時,将需要周遊整個結構,性能會相當低下;   

為了提高效率,Oracle引入了Bucket的資料結構,Oracle把管理所有的Buffer通過一個内部的Hash算法運算後,存放到不同Hash Bucket中,這樣通過Hash Bucket進行分割之後,衆多的Buffer被分布到一定數量的Bucket之中,當使用者需要在Buffer中定位資料是否存在是,隻需要通過同樣的算法獲得Hash值,然後到相應的Bucket中查找少量的Buffer即可确定。每個Buffer存放的Bucket由Buffer的資料塊位址運算決定;(這個算法從ORACLE官方得到的資訊很少,可以用索引的知識去了解)Bucket内部,通過Cache Buffer Chain将所有的Buffer通過Buffer Header資訊聯系起來; 

為了保護Bucket中的資料,每次通路的時候都需要先在記憶體中擷取latches後才能通路,整個通路的結構如圖:

深入了解latch: cache buffers chains

使用者記憶體中讀資料的順序:

a) 對該Block運用Hash算法,得到Hash值。

b)獲得獲得cache buffers chains latch

c) 到相應的Hash Bucket中搜尋相應Buffer Header

b)獲得cache buffers chains latch;

d) 如果找到相應的Buffer Header,然後判斷該Buffer的狀态,看是否需要構造CR Block,或者Buffer處于pin的狀态,最後讀取。e) 如果找不到,就從磁盤讀入到Buffer Cache中。

3、latch:cache buffers chains等待事件     

在Oracle9i以前,如果其它使用者程序已經獲得了這個latch,那麼新的程序就必須等待,直到該使用者程序搜尋完畢(搜尋完畢之後就會釋放該latch)。從Oracle9i開始 cache buffers chains latch可以隻讀共享,也就是說使用者程序A以隻讀(select)的方式通路Block,這個時候獲得了該latch,同時使用者程序B也以隻讀的方式通路Block,那麼這個時候由于是隻讀的通路,使用者程序B也可以獲得該latch。但是,如果使用者程序B要以獨占的方式通路Block,那麼使用者程序B就會等待使用者程序A釋放該latch,這個時候Oracle就會對使用者程序B标記一個latch:cache buffers chains的等待事件。

4、latch:cache buffers chains出現的原因   

4.1 不夠優化的SQL。   

大量邏輯讀的SQL語句就有可能産生非常嚴重的latch:cache buffers chains等待,因為每次要通路一個block,就需要獲得該latch,由于有大量的邏輯讀,那麼就增加了latch:cache buffers chains争用的機率。   對于正在運作的SQL語句,産生非常嚴重的latch:cache buffers chains争用,可以利用下面SQL檢視執行計劃,并設法優化SQL語句。

select * from table(dbms_xplan.display_cursor('sql_id',sql_child_number));   

如果SQL已經運作完畢,我們就看AWR報表裡面的SQL Statistics->SQL ordered by Gets->Gets per Exec,試圖優化這些SQL。

4.2熱點塊争用  

 1)查找資料庫是否存在latch的争用

select sid,event,p1text,p1raw from v$session_wait where event='latch: cache buffers chains';   

2)下面查詢查出Top 5 的争用的latch address。

select * from( select CHILD#,ADDR,GETS ,MISSES,SLEEPS from v$latch_children where name = 'cache buffers chains' and misses>0 and sleeps>0 order by 5 desc, 1, 2, 3) where rownum<6; 

3)然後利用下面查詢找出Hot block。    

 select        e.owner ||'.'|| e.segment_name  segment_name,       e.extent_id  extent#,       x.dbablk - e.block_id + 1  block#,       x.tch, x.tim ,l.child#     from       v$latch_children  l,       x$bh  x,       dba_extents  e     where       x.hladdr  = '&ADDR' and       e.file_id = x.file# and       x.hladdr = l.addr and       x.dbablk between e.block_id and e.block_id + e.blocks -1     order by x.tch desc ;       e.owner ||'.'|| e.segment_name  segment_name,       e.extent_id  extent#,       x.dbablk - e.block_id + 1  block#,       x.tch, x.tim ,l.child#     from       v$latch_children  l,       x$bh  x,       dba_extents  e     where       x.hladdr  = '&ADDR' and       e.file_id = x.file# and       x.hladdr = l.addr and       x.dbablk between e.block_id and e.block_id + e.blocks -1     order by x.tch desc ; 

4.3 Hash Bucket太少   需要更改_db_block_hash_buckets隐含參數。其實在Oracle9i之後,我們基本上不會遇到這個問題了,除非遇到Bug。是以這個是不推薦的,記住,在對Oracle的隐含參數做修改之前一定要咨詢Oracle Support。 

5、latch:cache buffers chains的模拟測試

5.1 建立表

SQL> create table john (no int,object_name varchar2(50)); 

5.2  插入資料S

QL> declare i int;beginfor i in 1..5 loopinsert into john  select  rownum as no,object_name from dba_objects;end loop;end;/ 

5.3 建立存儲過程SQL> create or replace procedure p_john isi int;icount int;beginfor i in 1..1000 loopselect count(*) into icount from john;end loop;end;/ 

5.4 模拟20并發全表掃描

SQL> var job_no number;S

QL> beginfor idx in 1..20 loopdbms_job.submit(:job_no,'p_john;');commit;end loop ;end;/ 

5.5檢視争用情況

SQL> select sid,event,p1text,p1raw from v$session_wait where event='latch: cache buffers chains';

深入了解latch: cache buffers chains

顯示存大量的latch等待;

 5.6  latch: cache buffers chains等待事件在awr報告中的特征

深入了解latch: cache buffers chains
深入了解latch: cache buffers chains
深入了解latch: cache buffers chains
深入了解latch: cache buffers chains
深入了解latch: cache buffers chains

總結以上的特征:

a)  占用大量的CPU資源;

b)  邏輯讀比正常情況要多很多;

c)  等待事件裡面肯定有latch: cache buffers chains

d)  Latch的命中率一般在95%以下,嚴重的在90%以下;

6、latch:cache buffers chains的個人解決方法很多時候應用的問題,其實是由于SQL品質導緻的,很多DBA吐槽:DBA和開發是不同的部門,是以要讓開發配合起來進行SQL調優難度較大,可行性較小。對于這種觀點本人表示不贊同:當系統出現大的問題的時候,會導緻系統性能下降,甚至當機,那麼如果這個系統重要的話,那麼DBA完全可以把問題的原因及解決方法發送給開發人員,并抄送公司上司,并說明原因及解決的方法,由于這個時候DBA是唯一知道問題的根源及解決方法的,是以上司也會支援你的;另外:SQL調優是最有效的調優方法,建議DBA别從系統的角度去進行處理,避免填了一個坑又冒出一個坑;

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

本文作者:JOHN

ORACLE技術部落格:ORACLE 獵人筆記               資料庫技術群:367875324 (請備注ORACLE管理 )  

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

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

轉載于:http://blog.itpub.net/12679300/viewspace-1244578/