ORACLE buffer cache 原理 --hash連結串列(參照學習:oracle核心技術揭秘)

lff1530983327發表於2016-08-30

對於一個塊,磁碟中叫block,記憶體中叫buffer。如何知道一個塊是否‘在buffer cache中呢?oracle 採用的是hash演算法。根據檔案號塊號來計算hash值,根據該值 定位到想用的bucket

每個hash  bucket中都儲存有一個指向cache buffer cache連結串列的連結串列頭。

bucket ——> buffer head (file_id,block_id)

CBC連結串列

當某些塊的hash值一樣的時候,可以被組織成一個連結串列,bucket中存放的是指向連結串列的連結串列頭。所以這個時候搜尋buffer的過程多了一個從BH中提取BA,按照BA(buffer address)訪問buffer

bucket ——> buffer head (file_id,block_id,BA)

找到 BH之後 要對BH進行加鎖 buffer pin ,所以在申請訪問連結串列前需先申請CBC latch。一般 一個CBC latch 要保護好幾個bucket ,其持有模式決定於 物件型別(唯一索引,非唯一索引等)、塊型別(根 ,葉)、操作(R W)、訪問路徑,除了唯一索引外,不管是W R CBC Latch都是以獨佔的模式持有。索引的根塊和枝塊只要不修改,都是以共享模式獲得。 因為查詢根塊 枝塊的頻率很高,所以會導致 CBC Latch那裡產生激烈的競爭。 最佳化:以共享的模式獲取CBC Latch,不需要修改buffer pin的轉態,出了普通的索引的根塊 枝塊外,在有唯一索引,索引唯一掃描的時候,索引的根塊 枝塊還有葉塊 表塊豆漿以共享的模式獲取CBC Latch。 用rowid直接邏輯讀 也是共享模式。

多個程式頻繁的以不相容的模式申請獲得某一CBC Latch 訪問此CBC Latch 保護的不同連結串列和不同的BH,這種現象為 熱鏈競爭。latch:cache buffer chains

多個程式頻繁的以不相容的模式申請獲得某一CBC Latch 訪問此CBC Latch 保護的同一連結串列下的同一BH ,這種現象為熱塊競爭。Mutex相關競爭。

在v$bh中可以檢視到特定檔案和塊的對應Latch,結合v$object可以檢視對應具體的保護物件。

在buffer pin加鎖的過程中是如何做到讀不阻塞寫的呢?因為在先發起的讀操作 在修改了buffer pin 為s之後已經釋放了CBC Latch ,此時寫操作可以正常獲取,修改讀程式的BH並將其status標記為CR,這對讀程式不產生影響。並且會克隆一個buffer status為XCUR。這是當寫程式釋放了CBC Latch  在獨佔的buffer pin的保護下修改buffer的時候,如果再有程式試圖對XCUR的BH加共享的buffer pin ,則該程式會被阻塞,即產生了 buffer busy wait。這就是10g之後的讀不阻塞寫,寫阻塞讀。

如果在迴圈 寫 和讀 操作的系統中,讀寫session 都有可能出現BBW 寫操作的BBW主要出現在回滾段塊上,因為構造CR塊時,讀會話會在undo block上的buffer加更高階別的共享buffer pin 這種pin會阻塞 寫會話向undo block中寫入前印象資料。

通常CBC Latch 和buffer busy wait都是熱塊競爭,使用更小的塊,增大pctfree或者重建表為hash 分割槽表。抬高高水位!

oracle修改一個buffer的步驟:

1>申請CBC Latch

2>獲取獨佔的buffer pin

3>釋放CBC Latch

4>生成redo(這個過程可以簡單概述為:現在PGA中記錄後映像資料,再傳到共享池中,然後傳到log buffer,如果log buffer沒有空間,程式先會等待LGWR重新整理log buffer中的空間,騰出空間後才能繼續(這時程式會等待log buffer space事件))

5>修改buffer 中的內容

6>申請持有CBC Latch

7>釋放獨佔buffer pin

8>釋放CBC Latch


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

相關文章