buffer cache深度分析及效能調整(六)
4.3.2 buffer busy waits等待
當一個session在讀取或修改buffer cache裡的記憶體資料塊時,首先必須獲得cache buffers chains latch,獲得以後,到hash chain上遍歷直到找到需要的buffer header後。這時,該session必須在該buffer header上以share或exclusive模式(具體哪個模式由該session的操作決定)獲得一個buffer lock或一個buffer pin。一旦buffer header被pin住,session就將釋放cache buffers chains latch,然後可以在該buffer上進行操作了。如果無法獲得buffer pin,那麼該session就會等待buffer busy waits等待事件。該等待事件不會出現在session的私有PGA裡。
buffer busy waits等待事件不能像latch free等待那樣可以相對比較容易的進行事後跟蹤。對於該等待事件,oracle提供了v$waitstat檢視。v$waitstat裡的記錄都是buffer busy waits等待事件發生時進行更新的。也就是說,該檢視體現的都是buffer busy waits等待事件的統計資料。但這隻能給你提供一個大概的buffer busy waits的分佈。如果要想具體的診斷該等待事件,只能當發生該等待時,到v$session_wait裡去找原因,從而才能找到解決的辦法。處理buffer busy wait等待事件時,首先使用下面的SQL語句找到發生等待的資料塊類別以及對應的segment。
select 'Segment Header' class,
a.segment_type, a.segment_name, a.partition_name
from dba_segments a, v$session_wait b
where a.header_file = b.p1
and a.header_block = b.p2
and b.event = 'buffer busy waits'
union
select 'Freelist Groups' class,
a.segment_type, a.segment_name, a.partition_name
from dba_segments a, v$session_wait b
where b.p2 between a.header_block + 1 and (a.header_block + a.freelist_groups)
and a.header_file = b.p1
and a.freelist_groups > 1
and b.event = 'buffer busy waits'
union
select a.segment_type || ' block' class,
a.segment_type, a.segment_name, a.partition_name
from dba_extents a, v$session_wait b
where b.p2 between a.block_id and a.block_id + a.blocks - 1
and a.file_id = b.p1
and b.event = 'buffer busy waits'
and not exists (select 1
from dba_segments
where header_file = b.p1
and header_block = b.p2);
然後,根據不同的資料塊型別進行相應的處理。
1) 如果資料塊型別為data block,如果版本為10g之前,則可以同時參照p3列的值來共同診斷。如果p3為130意味著同時有很多session在訪問同一個data block,而且該data block沒有在記憶體裡,而必須從磁碟上獲取。有三種方法可以降低該事件出現的頻率:
a、降低併發性。這個比較難實現。
b、找出並優化含有這些segment的SQL語句,以降低物理和邏輯讀。
c、增加freelists和freelist groups。
如果沒有足夠的freelists,當同時對同一個表進行insert時,這就很容易引起buffer busy waits等待。如果正在等待buffer busy waits的session正在進行insert操作,那麼需要檢查以下那個表有多少freelists了。當然,由於freelists的不足主要會導致對於segment header的buffer busy waits等待。
如果p3為220意味著有多個session同時修改在一個block(該block已經被讀入記憶體了)裡的不同的行。這種情況通常出現在高DML併發性的環境裡。有三種方法可以降低該事件出現的頻率:
a、降低併發性。這個比較難實現。
b、通過增加pctfree減少block裡含有的行數。
c、將該物件移到擁有較小block尺寸的表空間裡(9i或以上)。
2) 如果資料塊型別為data segment header(表或索引的segment header,不是undo segment header)上發生buffer busy waits等待事件,通常表明資料庫裡有些表或索引的段頭具有頻繁的活動。
程式訪問segment header主要有兩種原因:一是獲得或修改process freelists資訊;二是擴充套件HWM。有三種方法可以降低該事件出現的頻率:
a、增加爭用物件的freelists和freelist groups的數量。
b、確定pctfree和pctused之間的間隔不要太小。
c、確保next extent的尺寸不要太小。
d、9i以後,使用ASSM特性來管理block。
3) 如果資料塊型別為undo segment headers的爭用等待,表明資料庫中的rollback segments太少,或者他們的extent size太小,導致對於同一個segment header的大量更新。如果使用了9i以後的auto undo management,則不用處理,因為oracle會根據需要自動建立新的undo segments。如果是9i之前,則可以建立新的private rollback segments,並把它們online,或者通過降低transactions_per_rollback_segment引數來減輕該等待。
4) 如果資料塊型別為undo block,說明有多個session同時訪問那些被更新過的block。這是應用系統的問題,在資料庫來說對此無能為力。
4.3.3 free buffer waits等待
在一個資料塊被讀入buffer cache之前,oracle程式必須為該資料塊獲得一個對應的可用的記憶體數
據塊。當session在LRU list上無法發現一個可用的記憶體資料塊或者搜尋可用的記憶體資料塊被暫停的時候,該session就必須等待free buffer waits事件。
從前面的描述,我們已經知道,一個需要可用記憶體資料塊的前臺程式會連續掃描LRU 連結串列,直到達到一個限定值(也就是隱藏引數_db_block_max_scan_pct所指定的值,表示已經掃描的buffer header數量佔整個LRU連結串列上的buffer header的總數量,在9i中該限定值為40%)。如果到該限定值時還沒找到可用記憶體資料塊時,該前臺程式就會觸發DBWR程式以便清空一些髒資料塊,從而使得在輔助LRU連結串列上能夠掛上一些可用的記憶體資料塊。在DBWR程式工作時,該前臺程式就必須等待free buffer waits。
oracle跟蹤每次對於可用的記憶體資料塊的請求次數(記錄在v$sysstat裡的free buffer requested),也跟蹤每次請求可用的記憶體資料塊失敗的次數(記錄在v$system_event裡的free buffer waits的total_waits)。而v$sysstat裡的free buffer inspected則說明oracle為了找到可用的記憶體資料塊所所跳過的資料塊的個數,如果buffer cache很空,有很多空的資料塊的話,則該值為0。如果free buffer inspected相對free buffer requested來說很高,則說明oracle程式需要掃描更多的LRU連結串列上的資料塊才可以找到可用的資料塊。
SQL> select *
2 from v$sysstat
3 where name in ('free buffer requested', 'free buffer inspected');
STATISTIC# NAME CLASS VALUE
---------- ------------------------------ ----------- ----------
75 free buffer requested 8 290532493
79 free buffer inspected 8 2983596
SQL> select *
2 from v$system_event
3 where event = 'free buffer waits';
EVENT TOTAL_WAITS TOTAL_TIMEOUTS TIME_WAITED AVERAGE_WAIT TIME_WAITED_MICRO
----------------- ----------- -------------- ----------- ------------ -----------------
free buffer waits 1003 476 71075 71 710749256
可以看到,該系統的free buffer waits等待很少,總共等待的時間才0.476秒。同時也可以看到,請求了290532493(free buffer requested)個可用的記憶體資料塊,但是在這個過程中只跳過了2983596(free buffer inspected)個資料塊,二者相差2個數量級。說明系統很容易就找到可用的記憶體資料塊。
如果一個session花費了很多的時間等待free buffer waits等待事件的話,通常可能有以下原因:
1) 低效率的SQL語句:對於那些引起很大邏輯讀的SQL語句(v$sql裡的disk_reads),那些SQL語句可能進行了全表掃描,索引全掃描、或者通過了不正確的索引掃描表等。調整這些SQL語句以降低邏輯讀。
2) DBWR程式不夠多:也可以通過增加DBWR checkpoints的個數來降低free buffer waits。9i下,可以通過減小fast_start_mttr_target引數來縮短MTTR,從而增加DBWR程式啟動的次數。然而,這也有可能引起程式等待write complete waits事件。
3) I/O子系統太慢。
4) 延遲的塊清除(block clearouts):通常發生的情形是,晚上向資料庫匯入了一個很大的表。然後早上執行應用系統時,會發現有有程式在等待buffer busy waits。這是因為第一個訪問該表的程式將進行一個延遲的塊清除,而這會導致free buffer waits等待事件。解決方法是在匯入表完畢以後,執行一句全表掃描,比如通常是:select count(*) from該大表。這樣在後面的程式再次訪問的時候就不會產生free buffer waits等待事件了。
5) buffer cache太小:遇到free buffer waits事件,首先想到的就是增加buffer cache的大小。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9842/viewspace-399671/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- buffer cache深度分析及效能調整(五)
- buffer cache深度分析及效能調整(四)
- 調整緩衝區快取記憶體(Buffer Cache)的效能(轉)快取記憶體
- PGA自動管理原理深入分析及效能調整(六)
- Linux工具效能調優系列二:buffer和cacheLinux
- PGA自動管理原理深入分析及效能調整(五)
- PGA自動管理原理深入分析及效能調整(一)
- IO之核心buffer----"buffer cache"
- Oracle Cache Buffer ChainsOracleAI
- orcle效能調整(轉)
- 技術分享 | 調整 max-write-buffer-size 優化 pika 效能10倍的案例優化
- 33、buffer_cache_3(redo的產生、LRBA、buffer cache裡的等待事件)事件
- Buffer Cache以及buffer busy waits/gc相關事件AIGC事件
- 【BUFFER】Oracle buffer cache之 latch 學習記錄Oracle
- 【Cache】將常用的“小表”快取到Buffer Cache快取
- Linux Buffer/Cache 的區別Linux
- buffer與cache的區別
- 清理buffer/cache/swap的方法梳理
- PostgreSQL DBA(89) - Linux(Buffer vs Cache)SQLLinux
- Linux記憶體、Swap、Cache、BufferLinux記憶體
- SQL Server 2005效能調整二(zt)SQLServer
- Cache 和 Buffer 的區別在哪裡?
- Cache 和 Buffer 有什麼區別?
- 一次效能壓測及分析調優實踐
- Guava Cache:核心引數深度剖析和原始碼分析Guava原始碼
- 【效能調優】效能測試、分析與調優基礎
- 效能測試必備知識(11)- 怎麼理解記憶體中的Buffer和Cache?記憶體
- Linux如何手動釋放Swap、Buffer和CacheLinux
- Buffer的建立及使用原始碼分析——ByteBuffer為例原始碼
- dotnet高效能buffer
- [20231023]備庫與alter system flush buffer_cache.txt
- 手動釋放Linux上的Swap、Buffer和CacheLinux
- solaris記憶體引數調整及管理記憶體
- MAC下的homebrew安裝及映象調整Mac
- 達夢記憶體調整及修改方法記憶體
- In和exists使用及效能分析(三):in和exists的效能分析
- TiDB 效能分析&效能調優&優化實踐大全TiDB優化
- Tomcat高階特性及效能調優Tomcat