一個oracle block與data buffer中的一個buffer對應。
用戶進程(server process)負責讀取磁盤上的block到data buffer cache中,DEWn進程負責將髒塊寫到磁盤上。
一個buffer在data buffer中有4種狀態
pined:多個進程想寫這個塊,但只有1個進程能得到鎖。
claen :buffer中的數據和磁盤上的數據時一致的,這些塊將優先被淘汰。
free/unused:沒有被使用過,是空白內容。
dirty:不被某個進程使用使用,但buffer的內容和磁盤內容不一致
data buffer cache中用2個隊列保存buffer,一個隊列是LRU list,按照每一個buffer被訪問的時間排序,最近訪問的buffer排在最前。一個隊列是checkpoint queue,保存髒塊,DBWn進負責將這些髒塊寫到磁盤中。
建議將參數db_block_checksum設爲true,爲每一個block添加一個校驗碼,防止磁盤損壞引發數據丟失。
data buffer cache由多個相互獨立的buffer pool組成,每一個buffer對應一個block,不一樣的block size對應不一樣的buffer pool。
db_block_size決定了default,recycle,keep池中每一個buffer的大小。
db_cache_size:default池的大小。
db_recycle_cache_size:recycle池的大小。
db_keep_cache_size:keep池的大小。
也可經過設置SGA_TARGET,實現自動管理。
關於各data buffer cache大小的建議
select a.name,a.SIZE_FOR_ESTIMATE,a.ESTD_PHYSICAL_READ_FACTOR,a.ESTD_PHYSICAL_READS from
v$db_cache_advice a order by a.name,a.SIZE_FOR_ESTIMATE;
查看buffer cache的命中率
SELECT NAME, VALUE
FROM V$SYSSTAT
WHERE NAME IN ('db block gets from cache', 'consistent gets from cache', 'physical reads cache');
並使用公式1 - (('physical reads cache') / ('consistent gets from cache' + 'db block gets from cache')計算
或者在sql語句中直接計算
select 1-(sum(decode(name,'physical reads',value,0))/
(sum(decode(name,'db block gets',value,0))+
(sum(decode(name,'consistent gets',value,0)))))
from v$sysstat;
在多buffer pool狀況下,分別統計不一樣buffer pool的命中率
select name,1-(physical_reads/(db_block_gets+consistent_gets))
from v$buffer_pool_statistics
where db_block_gets+consistent_gets>0;
命中率須要和等待事件結合起來看性能狀況。
大表的全掃描會下降buffer cache的命中率
查看段在buffer cache中的佔用狀況,利用V$BH
方式一:查看每一個段有多少個塊在buffer cache中
SELECT o.OBJECT_NAME, COUNT(*) NUMBER_OF_BLOCKS
FROM DBA_OBJECTS o, V$BH bh
WHERE o.DATA_OBJECT_ID = bh.OBJD
AND o.OWNER != 'SYS'
GROUP BY o.OBJECT_NAME
ORDER BY COUNT(*);
方式二:查看指定段佔用buffer cache的比率
1.獲取段的object_id
SELECT DATA_OBJECT_ID, OBJECT_TYPE
FROM DBA_OBJECTS
WHERE OBJECT_NAME = UPPER('segment_name');
2.獲取指定段佔用了多少buffer
SELECT COUNT(*) BUFFERS
FROM V$BH
WHERE OBJD = data_object_id_value;
3.獲取當前buffer cache中有多少個buffer
SELECT NAME, BLOCK_SIZE, SUM(BUFFERS)
FROM V$BUFFER_POOL
GROUP BY NAME, BLOCK_SIZE
HAVING SUM(BUFFERS) > 0;
4.利用第3步和第4步的結果就能夠計算出該段在buffer cache中的佔用狀況。
對buffer cache調優的目標
server process可以在buffer cache中找到須要的數據
發生相應的等待事件的次數減小
調優的手段
下降sql語句對數據塊的請求
增長buffer cache的容量
把不一樣訪問模式的對方防到不一樣的pool中
將小表釘在內存中
直接讀
主要事件
Free Buffer Inspected: server process爲了在LRU鏈表上找到可用的內存數據塊所所跳過的數據塊的個數。
Free Buffer waits: server process通知DBWn寫髒塊的次數
Buffer busy waits: 找到buffer,但buffer被另外一個進程佔有,開始等待的次數。
000000000
查看Free Buffer Inspected產生的次數
select name,value from v$sysstat where name = 'free buffer inspected';
查看Free Buffer waits和Buffer busy waits發生的次數及耗用時間
select EVENT,TOTAL_WAITS,TIME_WAITED from v$system_event
where EVENT in('buffer busy waits','free buffer waits');
多個buffer pool
當對大表進行全表掃描時,可能會使其餘buffer(溫塊)移除buffer pool,將這些大表設置使用recycle pool。
recycle pool的容量應小於default pool,recycle pool中的buffer應儘快移出。
將溫塊設置爲使用keep pool。keep pool的容量應大於default pool。
alter table me.t_option storage(buffer_pool keep);
1個segment只能放在1個pool中。
v$cache,須要執行@?/rdbms/admin/catclust.sql腳本。與v$bh類型
select a.username,NAME,count(BLOCK#) from dba_users a join
v$cache b on a.USER_ID = b.owner#
where a.username != 'SYS'
group by OWNER#,a.username,NAME
order by a.username;
v$sess_io 記錄了每一個已鏈接session的讀取狀況的累計值
select b.USERNAME,a.BLOCK_GETS,a.CONSISTENT_GETS,a.PHYSICAL_READS
from v$sess_io a full join v$session b on a.SID=b.SID
where b.USERNAME is not null;
cache table
當使用全表掃描的方式查詢一張表時,會將該表相應的buffer放在LRU list的末尾,以便儘快淘汰,但有些小表須要全表掃描而不但願被淘汰掉,這時就須要使用cache table將表對應的buffer放在LRU list的開頭。能夠經過建立表,修改表,和sql提示實現cache table。建議被cache table的表不要太多,並放到keep pool中。cache table只能延長buffer在buffer pool中的存活時間,而不能將buffer pin在buffer pool中。
能夠在user_tables或all_tables或dba_tables中查詢cache字段查看錶是否被cache table。
Y :cache table N:沒有被cache table
例:create table cache_test(id int) cache;
alter table cache_test cache;
配置多個DBWn進程
配置參數db_writer_processes
在多cpu,異步IO的OS上能顯著提升性能。
參數disk_asynch_io是是否啓用異步IO的開關 true:打開
何時須要增長DBWn進程?若是等待事件Free Buffer waits佔有比較高比例時web