Oracle等待事件(一)—— latch cache buffers chains 分析与优化思路
一、 什么是CBC等待
首先我們需要知道CBC等待發生在哪里,為什么會發生,才能理解應該如何定位,如何處理。
首先,CBC latch是用于保護buffer cache的,因此CBC等待一定發生在buffer cache部分。
?
1.?如何定位數據塊是否在buffer cache中
首先,通過對數據塊所在的文件號和塊號進行hash計算,算出對應bucket號(hash bucket)。
沿著對應hash bucket所在hash chain list訪問鏈上的buffer header(bh,相關信息由x$bh視圖描述),hash chain list上掛載了一或多個bh,bh與Data block一一對應。
整體定位流程大致如下
?
2. CBC等待是如何發生的
從上圖中可以看到,一個latch負責保護多個hash bucket,如果有多個會話需要同時訪問一個hash chain list,就會在latch處發生爭用,只有一個會話可以持有latch,其余會話需要等待 latch cache buffers chains。
根據會話集中訪問對象的不同,cbc等待主要有兩種成因:
- 同一個cache buffers chains下不同block被頻繁訪問,稱為hot chains
- 同一個cache buffers chains下同一個block被頻繁訪問,稱為hot block
一個塊的訪問過程,一般會有2次cbc latch的獲取、釋放。
?
二、 如何分析CBC等待
分為兩種情況:等待正在發生(能從v$session查到),分析歷史的CBC等待(需要從v$ash或者dba_ash中獲取信息)。
1. CBC等待正在發生
當大量會話出現cbc等待,或者慢sql長時間處于cbc等待時可用。特征是v$session的event字段為?latch: cache buffers chains,可以根據 v$session P1RAW字段(內存地址原始值,16進制)找到內存地址對應對象。
select FILE#,DBARFIL,DBABLK,TCH from X$bh where HLADDR='v$session P1RAW字段' order by TCH desc; -- 多跑幾次找到排在前列的幾個 FILE# ? ?DBARFIL ? ? DBABLK ? ? ? ?TCH ---------- ---------- ---------- ----------48 ? ? ? ? 48 ? ?2454391 ? ? ? ?24048 ? ? ? ? 48 ? ? 488777 ? ? ? ?226401 ? ? ? ?401 ? ? ?29196 ? ? ? ?224DBARFIL為文件號,DBABLK為塊號,從dba_extents 查詢對應對象名,看在慢sql執行計劃中能否找到(是否為sql monitor activity占比最大的對象),如果有則可以對應處理(參考解決方法部分)。
select /*+ parallel(t,16)*/ * from dba_extents t where file_id=48 and 2454391 between block_id and block_id+blocks-1;?
也可以使用以下語句直接查詢
select?name, file#, dbablk, obj, tch, hladdr? from x$bh bh, obj$ owhere?o.obj#(+)=bh.obj andhladdr in? (select ltrim(to_char(p1,'XXXXXXXXXX') )from v$active_session_history?where event like 'latch: cache buffers chains'group by p1?having count(*) > 5 )and tch > 5 order by tch ??example outputNAME ? ? ? ? ?FILE# DBABLK ? ?OBJ TCH HLADDR ------------- ----- ------ ------ --- -------- BBW_INDEX ? ? ? ? 1 110997 ?66051 ?17 6BD91180 IDL_UB1$ ? ? ? ? ?1 ?54837 ? ? 73 ?18 6BDB8A80 VIEW$ ? ? ? ? ? ? 1 ? 6885 ? ? 63 ?20 6BD91180 VIEW$ ? ? ? ? ? ? 1 ? 6886 ? ? 63 ?24 6BDB8A80 DUAL ? ? ? ? ? ? ?1 ? 2082 ? ?258 ?32 6BDB8A80 DUAL ? ? ? ? ? ? ?1 ? 2081 ? ?258 ?32 6BD91180 MGMT_EMD_PING ? ? 3 ?26479 ?50312 272 6BDB8A80?
2.?分析歷史的CBC等待
- 查詢哪些sql遇到過大量cbc等待
找到sql_id后,可以具體分析其v$ash視圖P1,P2,P3字段,定位熱塊和對象信息。
- 查詢v$ash視圖P1,P2,P3字段含義
- 將p1表示的地址值轉換為16進制
- 關聯x$bh與obj$基表,找到熱塊及對應對象名,分析慢sql執行計劃看是否符合慢的原因
?
三、 解決方法
總的思路其實就是打散熱塊。
1. 加大表或索引pctfree(大表謹慎操作)
alter table 表名 pctfree 90; alter table 表名 move; alter index 索引名 rebuild;2. 表做hash分區
3. 使用hash簇表,打散數據存放位置
4. 過熱表改用全表掃描
將nest loop join改為merge join或hash join,如果對應表不大,可以嘗試將消耗最高的部分修改為全表掃描觀察效果
5. 使用反鍵或hash索引(針對索引)
6. 減少表空間block size,使每個數據塊中存放更少的行(慎用)
alter table <table_name> minimize records_pre_block;?
四、 其他
查詢遇到過最大cbc等待的塊
col object_name for a35 col cnt for 99999SELECTcnt, object_name, object_type,file#, dbablk, obj, tch, hladdr? FROM (select count(*) cnt, rfile, block from (SELECT /*+ ORDERED USE_NL(l.x$ksuprlat) */?--l.laddr, u.laddr, u.laddrx, u.laddrr,dbms_utility.data_block_address_file(to_number(object,'XXXXXXXX')) rfile,dbms_utility.data_block_address_block(to_number(object,'XXXXXXXX')) blockFROM?(SELECT /*+ NO_MERGE */ 1 FROM DUAL CONNECT BY LEVEL <= 100000) s,(SELECT ksuprlnm LNAME, ksuprsid sid, ksuprlat laddr,TO_CHAR(ksulawhy,'XXXXXXXXXXXXXXXX') objectFROM x$ksuprlat) l,(select ?indx, kslednam from x$ksled ) e,(SELECTindx, ksusesqh ? ? sqlhash, ksuseopc, ksusep1r laddrFROM x$ksuse) uWHERE LOWER(l.Lname) LIKE LOWER('%cache buffers chains%')?AND ?u.laddr=l.laddrAND ?u.ksuseopc=e.indxAND ?e.kslednam like '%cache buffers chains%')group by rfile, block) objs,?x$bh bh,dba_objects o WHERE?bh.file#=objs.rfileand ?bh.dbablk=objs.block ?and ?o.object_id=bh.obj order by cnt;CNT ?OBJECT_NAME ? ? ? TYPE ?FILE# ?DBABLK ? ?OBJ ? TCH ?HLADDR ---- ----------------- ----- ----- ------- ------ ----- --------1 WB_RETROPAY_EARNS TABLE ? ? 4 ? 18427 ?52701 ?1129 335F7C001 WB_RETROPAY_EARNS TABLE ? ? 4 ? 18194 ?52701 ?1130 335F7C003 PS_RETROPAY_RQST ?TABLE ? ? 4 ? 13253 ?52689 ?1143 33656D003 PS_RETROPAY_RQST ?INDEX ? ? 4 ? 13486 ?52692 ? 997 33656D003 WB_JOB ? ? ? ? ? ?TABLE ? ? 4 ? 14443 ?52698 ? 338 335B90805 PS_RETROPAY_RQST ?TABLE ? ? 4 ? 13020 ?52689 ? 997 33656D005 WB_JOB ? ? ? ? ? ?TABLE ? ? 4 ? 14676 ?52698 ? 338 335B9080查詢數據塊在buffer cache中有多少副本
select?count(*), name, file#, dbablk, hladdr? from ? x$bh bh, obj$ o where?o.obj#(+)=bh.obj andhladdr in? (select ltrim(to_char(p1,'XXXXXXXXXX') )from v$active_session_history?where event like 'latch: cache%'group by p1? ) group by name,file#, dbablk, hladdr having count(*) > 1 order by count(*);CNT NAME ? ? ? ?FILE# ?DBABLK HLADDR --- ---------- ------ ------- --------14 MYDUAL ? ? ? ? ?1 ? 93170 2C9F4B20?
參考
https://sites.google.com/site/embtdbo/wait-event-documentation/oracle-latch-cache-buffers-chains
https://yq.aliyun.com/articles/208510
https://www.slideshare.net/khailey/oracle-10g-performance-chapter-06-buffer-cache
總結
以上是生活随笔為你收集整理的Oracle等待事件(一)—— latch cache buffers chains 分析与优化思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java基础重温_02:运算符、三元运算
- 下一篇: RabbitMQ在Windows环境下的