天天看點

Buffer cache 的調整與優化(二)

--********************************

-- Buffer cache 的調整與優化(二)

--********************************

Buffer cache 實際上細分為多個不同的Buffer cache,如keep pool,recycle pool,default pool,下面描述不同buffer cache的使用。

有關Buffer cache 的總體描述,請參考:Buffer cache 的調整與優化(一)

一、不同buffer pool的應用

一個buffer pool即對應于一個oracle 資料塊,三種不同的pool實際上是針對在data buffer cache中塊的通路的程度不同在通常的

慣例下采取的方法。即對最熱塊,次熱快,以及冷塊存放到不同的buffer pool中。實際上這幾個不同的buffer pool除了配置設定的大小不同

之外,所采用的算法都是LRU算法,是以對塊的緩存以及淘汰(aged out)算法實質一樣。

任意一個不同的buffer pool都将根據通路方式的不同而隻緩存讀取到的資料塊,即如果是全表掃描,則緩存所有塊,如果是索引快速

掃描,則緩存索引的所有葉節點塊。

keep buffer cache --對應keep pool

recycle buffer cache --對應recycle pool

nk buffer caches --對應db_nk_cache_size

default buffer cache --對應dafault pool

keep pool:

對于經常通路的小表将其常駐記憶體,即放置到keep pool。其作用是保證這部分經常通路的資料能夠常駐記憶體而不被替換出記憶體,

進而提高通路這些資料的速度。這個池最好能夠保持99%的命中率,也就是說要保證這個池的大小能夠緩存放于這個池的大部分對象。

recycle pool:

對于不經常通路的大segment,就可以考慮将其放置到recycle pool,以盡快将其淘汰出去。

dafault pool:

普通對象的緩沖池,那些沒有在keep pool也沒有在recycle pool的對象将緩沖到這裡。

nk buffer caches

主要适用于不同平台傳輸表空間,或根據業務需要來使用非标準表空間之外的表空間。

如磁盤上資料檔案的最小I/O單元叫block一樣,buffer cache的最小單元(或者說結構)叫buffer。

每個buffer跟x$bh中每條記錄存在一一對應關系。

注意:

default buffer cache = db_cache_size - db_keep_cache_size - db_recycle_cache_size - db_nk_cache_size

sys@ORCL> select * from v$version where rownum < 2;

BANNER

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

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

sys@ORCL> select name,bytes/1024/1024 from v$sgainfo where name='Buffer Cache Size';

NAME BYTES/1024/1024

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

Buffer Cache Size 192

sys@ORCL> select name,current_size,buffers,block_size FROM v$buffer_pool;

NAME CURRENT_SIZE BUFFERS BLOCK_SIZE

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

DEFAULT 192 23952 8192

sys@ORCL> alter system set db_recycle_cache_size=16m;

sys@ORCL> alter system set db_keep_cache_size=16m;

sys@ORCL> select name,current_size,buffers,block_size FROM v$buffer_pool;

NAME CURRENT_SIZE BUFFERS BLOCK_SIZE

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

KEEP 16 1996 8192

RECYCLE 16 1996 8192

DEFAULT 160 19960 8192

sys@ORCL> alter system set db_16k_cache_size=4m;

sys@ORCL> select name,current_size,buffers,block_size FROM v$buffer_pool;

NAME CURRENT_SIZE BUFFERS BLOCK_SIZE

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

KEEP 16 1996 8192

RECYCLE 16 1996 8192

DEFAULT 160 19960 8192

DEFAULT 4 252 16384

從上面的設定可以看出,任意一個buffer pool大小的調整,不影響整個buffer_pool的大小。即任意buffer pool的增加,将使得

default buffer pool的減小,反之,任意buffer pool尺寸的減少,default buffer pool的尺寸将會增加。

其次,任意buffer pool的增加應考慮到Oracle 以及OS是否有足夠的記憶體來進行配置設定。如果是使用了ASMM管理,則應考慮整個

sga_target < sga_max_size。

二、大表段、大索引段随機通路的問題

當使用LRU算法時,對于大表段,索引段的随機通路,容易導緻其他的并非最頻繁通路的熱點塊從cache中被aged out.此外,這些随機通路

的資料塊并不屬于熱塊,也很容易随時被替換,通過下面的三種方法來避免該情況的産生:

1.如果受影響的對象是索引,則判斷是否是精确的索引選擇,如果不是,則調整SQL語句。

2.如果SQL語句已優化,則可以将被通路的大段存放到recycle cache中。

3.可以将一些小的熱點塊移入到keep buffer pool,keep buffer pool能夠最小化cache的丢失。

三、多個buffer pool的設定

db_cache_size

db_keep_cache_size

db_recycle_cache_size

db_nk_cache_size

以上的參數為動态參數,使用下面的方式來調整,可以基于記憶體調整,也可以将參數更改到spfile。

alter system set db_keep_cache_size=nm scope = both | memory | spfile;

alter system set db_16k_cache_size=nm;

alter system set db_recycle_cache_size=nm;

闩由Oracle RDBMS來自動配置設定

進行了上述設定之後,可以基于這些不同的緩沖池來建立對象

create index idx_obj

storage(buffer_pool keep);

alter table tb_obj

storage(buffer_pool recycle);

alter index idx_obj

storage(buffer_pool keep);

注:

四個池除了使用不同的名稱且産生不同的作用之外,其内部算法實質是一樣的,都是采用LRU算法。

一個segment隻能放入到一個buffer pool中.如果一個表或索引對象擁有多個segment,則不同的segment可以存放到不同的buffer pool.

如何決定什麼樣的segment存放到何種buffer cache則根據業務需求來定。

如果沒有指定buffer_pool短語,則表示該對象進入default類型的buffer cache。

四、keep buffer pool的使用與優化

将常用的小表對象常駐記憶體

一般情況是對象的大小應當為少于default buffer pool 大小的10%。

根據下面的方法計算對象所占用塊的總數,且該塊的總數大小應當小于于keep buffer pool的大小。

計算所有将要放入到keep buffer cache對象的總塊數得到一個近似值,然後将稍微大于該近似值的尺寸指定給keep buffer pool。

可以通過查詢DBA_TABLES.BLOCKS 和DBA_TABLES.EMPTY_BLOCKS 獲得塊的資訊或者通過V$BH檢視segment所占用的buffer。

對于放入keep buffer pool中的表資料,如果對象塊多于buffer pool數量,則以buffer pool數量為準進行緩存,冷塊将被新塊置換。

注:如果位于keep buffer pool中的對象尺寸增大,将不會被填充到keep buffer pool。

其次,如果有多個對象緩存到keep buffer pool,而keep buffer pool不足以緩存這些對象,按LRU算法,先前位于keep buffer

pool 的對象一樣會被aged out。

首先使用包收集對象資訊

sys@ORCL> exec dbms_stats.gather_table_stats('SCOTT','BIG_KEEP');

sys@ORCL> select table_name,blocks,empty_blocks

2 from dba_tables where owner='SCOTT' and table_name='BIG_KEEP';

TABLE_NAME BLOCKS EMPTY_BLOCKS

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

BIG_KEEP 180 0

設定keep buffer pool的大小

alter system set db_keep_cache_size=16m scope = both ; --注意,該參數值的大小應根據實際情況設定

将對象放置的keep buffer pool

alter table big_keep

storage(buffer_pool keep);

五、recycle buffer pool的使用與優化

一旦事務被送出則這些塊将從recycle buffer pool中被清除

對象的大小應當為多于default buffer pool 大小的兩倍

recycle buffer pool需要具有一個事務所需要的全部塊

下面将big_temp 置入到recycle buffer pool

sys@ORCL> exec dbms_stats.gather_table_stats('SCOTT','BIG_RECYCLE');

scott@ORCL> select blocks,empty_blocks from dba_tables

2 where table_name='BIG_RECYCLE' and owner='SCOTT';

BLOCKS EMPTY_BLOCKS

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

1062 0

alter system set db_recycle_cache_size=16m scope = both ; --注意,該參數值的大小應根據實際情況設定

scott@ORCL> alter table big_recycle

2 storage(buffer_pool recycle);

使用視圖v$cache,

SELECT owner#

,NAME

,COUNT(*) blocks

FROM v$cache

GROUP BY owner#,NAME;

SELECT s.username --跟蹤recycle buffer pool的I/O情況

,io.block_gets

,io.consistent_gets

,io.physical_reads

FROM v$sess_io io,v$session s

WHERE io.sid=s.sid;

六、獲得buffer pool中的相關資訊

視圖v$bh(基于視圖x$bh)顯示目前位于SGA中所有塊的詳細資訊。決定哪個段位于哪個緩沖區,所占住的塊的個數等

1.查詢buffer cache中不同對象占住塊的個數(可以根據查詢将不經常通路的大對象置于到recycle pool)

SELECT o.owner, object_name, object_type, COUNT(1) buffers --這個查詢獲得到經常通路的對象,可以将其放到recycle pool中

FROM SYS.x$bh, dba_objects o

WHERE (tch = 1 OR (tch = 0 AND lru_flag < 8))

AND obj = o. object_id

AND o.owner NOT IN ('SYSTEM', 'SYS')

GROUP BY o.owner, object_name, object_type

ORDER BY buffers;

SELECT o.owner, object_name, object_type, COUNT(1) buffers --這個查詢獲得到經常通路的對象,可以将其放到keep pool中

FROM SYS.x$bh, dba_objects o

WHERE tch > 10

AND lru_flag = 8

AND obj = o.object_id

AND o.owner NOT IN ('SYSTEM', 'SYS')

GROUP BY o.owner, object_name, object_type

ORDER BY buffers;

2.查詢單個對象占住buffer cache中塊的總個數

SELECT COUNT(*)

FROM v$bh

WHERE objd=(

SELECT data_object_id

FROM Dba_Objects

WHERE object_name=UPPER('big_table')

AND owner='SCOTT'

AND status != 'free');

COUNT(*)

----------

4235

3.獲得所有不同的buffer pool 目前配置設定塊的總個數

SELECT NAME

,block_size

,SUM(buffers)

FROM v$buffer_pool

GROUP BY NAME,block_size

HAVING SUM(buffers)>0;

NAME BLOCK_SIZE SUM(BUFFERS)

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

DEFAULT 8192 8958

KEEP 8192 1996

DEFAULT 16384 252

RECYCLE 8192 1996

4.獲得單個對象占用buffer cache的比率

SELECT round(obj_cnt/totalcache_cnt*100,3)

FROM

(SELECT COUNT(*) AS obj_cnt

FROM v$bh

WHERE objd=(

SELECT data_object_id

FROM Dba_Objects

WHERE object_name=UPPER('big_table')

AND owner='SCOTT'))a,

(SELECT NAME

,block_size

,SUM(buffers) AS totalcache_cnt

,COUNT(*)

FROM v$buffer_pool

WHERE NAME='DEFAULT'

GROUP BY NAME,block_size

HAVING SUM(buffers)>0) b;

ROUND(OBJ_CNT/TOTALCACHE_CNT*100,3)

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

.015

七、查詢不同的buffer pool的命中率(buffer cache hit ratio)

低ratio并不能表明增加cache size可以提高性能。高ratio有時反而會讓你誤認為cache size已經足夠大而滿足要求了。比如:重複的掃描

一些大表或索引。然後大表的全表掃描往往都是實體讀,會人為的降低hit ratio。是以在不同高峰時段,多次采集資料非常有必要(或使用

StatsPack。

Db_cache_size 是針對預設的db_block_size的,對于非标準的block,要特别指定DB_nK_CACHE_SIZE 參數。

SELECT NAME,

block_size,

physical_reads,

db_block_gets,

consistent_gets,

(1 -(physical_reads / (DECODE(db_block_gets, 0, 1, db_block_gets) +

DECODE(consistent_gets, 0, 1, consistent_gets)))) * 100 "Hit Ratio"

FROM V$BUFFER_POOL_STATISTICS

ORDER BY NAME;

NAME BLOCK_SIZE PHYSICAL_READS DB_BLOCK_GETS CONSISTENT_GETS Hit Ratio

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

DEFAULT 16384 63 5 128 52.632

DEFAULT 8192 21013 230479 879158 98.106

KEEP 8192 0 0 0 100.000

RECYCLE 8192 106 0 434 75.632

八、總結

盡管使用不同的緩沖池從某種程度上來說可以大大提高資料庫系統的I/O,給予了DBA更多的選擇性。然而,多個緩沖池(buffer pool)

增加了管理的複雜度,其次由于不同的緩沖池不能夠共享,在某種程度上來說,勢必造成buffer cache大小的浪費。是以,如果default

buffer pool能夠滿足現有的需求,盡可能的避免使用過多的緩沖池帶來管理的不便。

九、更多參考

有關性能優化請參考

Oracle 硬解析與軟解析

共享池的調整與優化(Shared pool Tuning)

Buffer cache 的調整與優化(一)

Oracle 表緩存(caching table)的使用

有關閃回特性請參考

Oracle 閃回特性(FLASHBACK DATABASE)

Oracle 閃回特性(FLASHBACK DROP & RECYCLEBIN)

Oracle 閃回特性(Flashback Query、Flashback Table)

Oracle 閃回特性(Flashback Version、Flashback Transaction)

有關基于使用者管理的備份和備份恢複的概念請參考:

Oracle 冷備份

Oracle 熱備份

Oracle 備份恢複概念

Oracle 執行個體恢複

Oracle 基于使用者管理恢複的處理(較長的描述了媒體恢複及其處理)

有關RMAN的恢複與管理請參考:

RMAN 概述及其體系結構

RMAN 配置、監控與管理

RMAN 備份詳解

RMAN 還原與恢複

有關Oracle體系結構請參考:

Oracle 執行個體和Oracle資料庫(Oracle體系結構)

Oracle 表空間與資料檔案

Oracle 密碼檔案

Oracle 參數檔案

Oracle 資料庫執行個體啟動關閉過程

Oracle 聯機重做日志檔案(ONLINE LOG FILE)

Oracle 控制檔案(CONTROLFILE)

Oracle 歸檔日志