標籤:des style io 使用 ar 檔案 資料 問題 sp
Buffer cache 的原理
一、
1·)當一個伺服器處理序需要讀資料到buffer cache中時,首先必須判斷該資料在buffer 中是否存在,如果存在且可用,則擷取該資料,根據lru演算法在lru list上移動該block;如果buffer中不存在該資料,則需要從資料檔案上擷取
2)在讀取資料之前,server進程需要掃描lru list 尋找free的buffer,掃描過程中server進程會把發現的所有已經被修改過的buffer移動到checkpoint queue上,這些dirty buffer隨後可以被寫出到資料檔案。
3)如果checkpoint queue超過了閾值,server進程會通知dbwn去寫出髒資料;這也是出發dbwr寫的一個條件。
Select kvittag,kvitval,kbvitdsc from x$kvit where kvittag=’kcbldq’;
如果server進程掃描lru超過一個閾值仍然不能找到足夠的free buffer ,將停止尋找,轉而通知dbwn去寫出髒資料,釋放空間。
Select kvittag,kvitval,kbvitdsc from x$kvit where kvittag=’kcbfsp’;
同時由於增量檢查點的引入,dbwn進程也會主動掃描lru list,將發現的dirty buffer 移動至checkpoint queue,這個掃描也受到一個內部 約束,
Select kvittag,kvitval,kbvitdsc from x$kvit where kvittag=’kcbdsp’;
4)找到足夠的buffer之後,server進程就可以將buffer從資料檔案讀入buffer cache
5)如果讀取的block不滿足讀一致性要求,則server進程需要通過當前block版本和復原段構造前鏡像返回給使用者。
從oracle 8i開始lru list 和dirty list 引入了輔助的list,用於提高管理效率,當資料庫初始化時,buffer首先存放在lru的輔助list上,當被使用後移動到lru 的主list上,這樣當使用者進程搜尋free buffer時,首先從輔助list上搜尋,當dbwr搜尋dirty buffer時 會首先從lru 的主list上進行搜尋,提高了搜尋效率和資料庫效能。
二、轉儲buffer cache 的內容(1-10級)
Alter session set events ‘immediate trace name buffers level 4’;
Level 1:僅包含buffer headers 的資訊。
Level 2:包含buffer headers和buffer概要資訊轉儲
Level 3:包含buffer headers和完整buffer內容轉儲。
三、cache buffer lru chain 閂鎖競爭與解決
當使用者進程需要讀資料到buffer cache時,或cache buffer根據lru演算法進行管理時,就不可避免地要掃描lru list 擷取可用buffer或更改buffer狀態。在搜尋的過程中必須擷取latch,鎖定lru的latch就是常見到的cache buffers lru chain
解決該latch競爭的方法:
1)適當的增加buffer cache,這樣既可以減少讀資料到buffer cache的機會,減少掃描lru list 的競爭
。
2)可以適當增加lru latch 的數量,修改_db_block_lru_latches 參數可以實現,
3)通過多緩衝池技術,可以減少不希望的資料老化和全表掃描等操作對於default池的衝擊,從而減少競爭。
四、cache buffer chain 閂鎖競爭與解決
1、在lru和checkpoint queue這兩個記憶體結構之外,buffer cache的管理還存在另外兩個重要的資料結構:hash bucket 和 cache buffer chain
2、為了提高oracle 確定某個block在buffer中的位置,oracle引入了bucket的資料結構,oracle把管理的所有buffer通過一個內部的hash演算法運算之後,存放到不同hash bucket中,這樣通過hash bucket進行分割之後,眾多的buffer 被分布到一定數量的bucket之中,當使用者需要在buffer中定位元據是否存在時,只需要通過同樣的演算法獲得hash值,然後到相應的bucket中尋找少量的buffer即可確定。每個buffer存放的bucket由buffer的資料區塊地址運算決定。
Bucket 內部,通過cache buffer chain (一個雙向鏈表)將所有的buffer通過buffer header資訊聯絡起來。
Buffer header 存放的是對應資料區塊的概要資訊,包括資料檔案號、塊地址、狀態等。要判斷資料區塊在buffer中是否存在,通過檢查buffer header即可確定。
3、bucket的數量受一個隱含參數的影響:
Db_block_hash_budkets
1) 從oracle 8i開始,bucket的數量比以前大大增加,通過增加的bucket的稀釋使得每個bucket上的buffer數量大大減少。
2) oracle 8i之前,_db_block_hash_laches的數量和bucket的數量是一致的,每個latch管理一個bucket;從oracle 8i開始每個latch管理多個bucket,由於每個bucket上的buffer數量大大降低,所以latch的效能反而得到了提高。
3) 每個bucket存在一條cache buffer chain
4) Buffer header 上存在指向具體buffer的指標。
5) 瞭解了以上演算法後,可以想象,如果大量進程對相同的block進程進行操作,那麼必然引發cache buffer chain的競爭,也就是通常所說的熱快競爭。
五、x$bh和 buffer header
每個buffer在x$BH中都存在一條記錄。
X$BH中有一個重要欄位TCH ,TCH為touch的縮寫,表示一個buffer的訪問次數,buffer被訪問的次數越多,說明該buffer越搶手,也就是可能存在熱點塊競爭的問題
查詢當前資料庫最繁忙的buffer
Select *
From (select addr,ts#,file#,dbarfil,dbablk,tch
From x$bh
Order by tch desc)
Where rownum<11;
結合dba_extents中的資訊,可以查詢到這些熱點buffer都來自那些對象。
Select e.owner,e.segmet_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)
Where e.relative_fno=b.dbarfl
And e.block_id<=b.dbablk
And e.block_id+e.blocks>dbablk;
如果需要確定熱點塊對象,可以從v$latch_children中查詢具體的子latch資訊。
X$BH中還存在另外一個關鍵字段hladdr 即hash chain latch address,這個欄位可以和v$latch_child.addr進行關聯,這樣就可以把具體的latch競爭和資料區塊關聯起來。再結合dba_extents視圖再結合v$sqlarea或者v$sqltext找到頻繁操作這些對象的sql,然後對其進行最佳化,即可緩解或解決熱點競爭的問題。
oracle buffer cache的基本原理