buffer cache 的學習
buffer cache 的概念以及作用:
buffer cache用來存放從資料檔案讀取來的資料的一個copy,buffer中存放最近被使用的資料,并使用LRU算法來管理, oracle 使用Buffer Touch Counts,來代替頻繁的移動連結清單 。oracle使用buffer cache 的目的有一下兩點:
1.優化實體I/O 資料庫在buffer cache更新資料庫并且在redo log buffer 中存放原資料的改變。。。。當commit之後,redo log buffer中的資料會馬上寫入磁盤但是buffer cache不會馬上寫到磁盤中。這樣就能避免頻繁的讀寫磁盤的實體I/O
2.保持頻繁的讀寫cache并且減少對磁盤的寫操作。。。 資料庫可以通過讀取buffer cache 代替讀取實體磁盤改善性能。
buffer 的狀态
Unused(未使用的) : 這類buffer 從來沒被使用過,是以也最容易被使用。 Clean(幹淨的):這類buffer的資料是幹淨的,就是已經存在檢查點,被寫入到了磁盤。是以這類buffer也容易使用,不需要設定檢查點。 dirty(髒的):這類buffer中的資料是髒資料,當要使用這部分buffer是必須設定檢查點,将資料寫入到磁盤中,才能使用.
當buffer cache 真在被使用時,它就被pin住了。。。
buffer 的模式
Current mode(目前模型): current mode get 也稱為 db block get, 它是檢索目前存在于cache中的資料塊。比如說:一個沒有送出的事務更新了一個資料塊中的兩條資料,此時 db block get檢索資料就會檢索到兩條已經更新的資料。一般會出現在更新語句中。
Consistent mode(一緻性模式): consistent mode 是檢索資料塊的一緻性讀,這個模式有可能會使用undo data。比如說:一個沒有送出的事務更新了一個資料庫中的兩條資料,此時當其它使用者查詢這兩條資料時,Oracle會使用undo data還原出這個資料庫一緻性讀的狀态,并不包含目前更新了的資料(consistent read clone )。 buffer 寫入資料到磁盤:
DBWn 程序階段性将LRU末端的髒資料寫入磁盤中,一般觸發Oracle寫入程序在以下的情況中:
- A server process cannot find clean buffers for reading new blocks into the database buffer cache.
- The database must advance the checkpoint, which is the position in the redo thread from which instance recovery must begin.
- Tablespaces are changed to read-only status or taken offline.
預測buffer cache 的大小對實體I/O的影響,可以使用 V$DB_CACHE_ADVICE
SELECT size_for_estimate, buffers_for_estimate, estd_physical_read_factor, estd_physical_reads
FROM V$DB_CACHE_ADVICE
WHERE name = 'DEFAULT'
AND block_size = (SELECT value FROM V$PARAMETER WHERE name = 'db_block_size')
AND advice_status = 'ON';
根據執行上面語句,我們可以看到當buffer cache 為272M時,而不是304M時,實體讀會增加1.74倍或者是74%,是以不建議設定buffer cache為212M。
當buffer cache 增加到334M時,實體讀會減少7%,是以當SGA_MAX設定允許的情況下,建議增加buffer cache的大小。
Estd Phys Estd Phys
Cache Size (MB) Buffers Read Factor Reads
---------------- ------------ ----------- ------------
30 3,802 18.70 192,317,943 10% of Current Size
60 7,604 12.83 131,949,536
91 11,406 7.38 75,865,861
121 15,208 4.97 51,111,658
152 19,010 3.64 37,460,786
182 22,812 2.50 25,668,196
212 26,614 1.74 17,850,847
243 30,416 1.33 13,720,149
273 34,218 1.13 11,583,180
304 38,020 1.00 10,282,475 Current Size
334 41,822 .93 9,515,878
364 45,624 .87 8,909,026
395 49,426 .83 8,495,039
424 53,228 .79 8,116,496
456 57,030 .76 7,824,764
486 60,832 .74 7,563,180
517 64,634 .71 7,311,729
547 68,436 .69 7,104,280
577 72,238 .67 6,895,122
608 76,040 .66 6,739,731 200% of Current Size
計算buffer cache 的命中率
1.計算buffer cache 命中率所需要的一些資料如下
Statistic | Description |
---|---|
| Number of times a consistent read was requested for a block from the buffer cache. |
| Number of times a CURRENT block was requested from the buffer cache. |
| Total number of data blocks read from disk into buffer cache. |
Example 7-1 Calculating the Buffer Cache Hit Ratio
SELECT NAME, VALUE
FROM V$SYSSTAT
WHERE NAME IN ('db block gets from cache', 'consistent gets from cache', 'physical reads cache');
Using the values in the output of the query, calculate the hit ratio for the buffer cache with the following formula:
1 - (('physical reads cache') / ('consistent gets from cache' + 'db block gets from cache'))
計算命中率的sql 如下
select db_block_gets,consistent_gets,physical_read,1 - (physical_read / (db_block_gets + consistent_gets))
from (
SELECT max(decode(name, 'db block gets from cache', value, null)) as db_block_gets,
max(decode(name, 'consistent gets from cache', value, null)) as consistent_gets,
max(decode(name, 'physical reads cache', value, null)) as physical_read
FROM V$SYSSTAT
WHERE NAME IN ('db block gets from cache','consistent gets from cache','physical reads cache')
);
根據oracle文檔,buffer cache命中率保持在98%以上比較好。。。。。。
V$BH顯示出了目前在SGA中占用資料塊的對象,可以确定每個Segment使用了多少記憶體空間。
Oracle提供了兩種方法: Method 1
The following query counts the number of blocks for all segments that reside in the buffer cache at that point in time. Depending on buffer cache size, this might require a lot of sort space.
COLUMN OBJECT_NAME FORMAT A40
COLUMN NUMBER_OF_BLOCKS FORMAT 999,999,999,999
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(*);
Method 2
Use the following steps to determine the percentage of the cache used by an individual object at a given point in time:
- Find the Oracle Database internal object number of the segment by entering the following query:
SELECT DATA_OBJECT_ID, OBJECT_TYPE
FROM DBA_OBJECTS
WHERE OBJECT_NAME = UPPER('segment_name');
Because two objects can have the same name (if they are different types of objects), use the OBJECT_TYPE column to identify the object of interest. - Find the number of buffers in the buffer cache for SEGMENT_NAME :
SELECT COUNT(*) BUFFERS
FROM V$BH
WHERE OBJD = data_object_id_value;
where data_object_id_value is from step 1. - Find the number of buffers in the instance:
SELECT NAME, BLOCK_SIZE, SUM(BUFFERS)
FROM V$BUFFER_POOL
GROUP BY NAME, BLOCK_SIZE
HAVING SUM(BUFFERS) 0;
- Calculate the ratio of buffers to total buffers to obtain the percentage of the cache currently used by SEGMENT_NAME :
v$db_cache_advice 表結構如下:
列名 | 資料類型 | 說明 |
---|---|---|
| | 緩沖池辨別号(從1到8,1-6對應于DB_nK_CACHE_SIZE,DB_CACHE_SIZE與系統标準塊尺寸的序号相關,如DB_BLOCK_SIZE為8K,則DB_CACHE_SIZE的辨別号為3(2,4,8…)。7是DB_KEEP_CACHE_SIZE,8是DB_RECYCLE_CACHE_SIZE) |
| | 緩沖池名稱 |
| | 該池中的緩沖區的塊大小(以位元組為機關)。可能的值:标準塊大小,2的幂非标準的塊大小, , , , , . |
| | 建議器狀态:ON表示建議器在運作,OFF表示建議器已經關閉。當建議器關閉了,視圖中的資料是上一次打開所統計得出的 |
| | 預測性能資料的Cache大小(M為機關) |
| | 預測的Cache大小因子(即與目前大小的比例) |
| | 預測性能資料的Cache大小(緩沖塊數) |
| | 這一緩沖大小時,實體讀因子,它是如果緩沖大小為SIZE_FOR_ESTIMATE時,建議器預測實體讀數與目前實際實體讀數的比率值。如果目前實體讀數為0,這個值為空。 |
| | 如果緩沖大小為SIZE_FOR_ESTIMATE時,建議器預測實體讀數。 |
| | 當緩沖池的大小為size_for_estimate時需要的實體讀的時間。 |
| | 當緩沖池為size_for_estimate是實體讀所消耗時間的百分比 |
| | 為讀取的資料塊的總數。隻對RAC有效 |
| | 讀取花費的總時間。隻對rac有效 |