Cache Buffer Chain Latch等待事件
產生的背景:
Oracle為了將物理IO最小化,把最近使用過的資料塊保持在記憶體中。為了管理這些記憶體,oracle 使用如圖的結構,
Hash Chain的結構,Hash Chain位於共享池中,使用典型記憶體結構Bucket->Chain->Header結構進行管理。
Hash Chain結構的起點是Hash表,Hash表由多個hash bucket組成,塊地址 是由file#+block#組成的,當掃描塊時使用Hash函式
進行hash運算,使用hash值查詢hash bucket,具有相同hash值的buffer haeder在hash bucket上以chain形式連結。
Buffer header有指向實際緩衝區的指標。注意:Hash Chain結構是在共享池中,而實際緩衝區資訊儲存在高速緩衝區中。
Hash Chain結構利用cache buffers chain Latch來保護。
當程式掃描特定的資料塊時,必須獲得相應資料塊所在Hash Chain管理的cache buffers chain Latch。基本上
一個程式獲得僅有的一個cache buffers chain Latch,一個cache buffers chain Latch管理多個Hash Chain。
當多個程式同時檢索Buffer Cache時,獲得cache buffers chain Latch的過程中發生爭用,就會產生
cache buffers chain Latch等待事件。
程式掃描特定的資料塊整個過程。
1、Oracle以每個塊的檔案號、塊號和型別做HASH運算,得到HASH值。根據HASH值,到HASH表中取出指定塊的記憶體地址
2、獲取CBC Latch
3、根據HASH值,搜尋CBC連結串列
4、根據DBA找到BH(Buffer Header)加Buffer Pin
5、加完Buffer Pin馬上釋放CBC Latch
6、訪問Buffer開始fetch資料
7、獲取CBC Latch
8、釋放Buffer Pin
9、釋放CBC Latch
使用SQL語句可以獲得hash_latches,hash_buckets數量,因此一個鎖存器保護Bucket數量是1048576/32768=32個。
SQL> select x.ksppinm name,
2 y.ksppstvl value,
3 y.ksppstdf isdefault,
4 decode(bitand(y.ksppstvf, 7),
5 1,
6 'MODIFIED',
7 4,
'SYSTEM_MOD', 8
9 'FALSE') ismod,
10 decode(bitand(y.ksppstvf, 2), 2, 'TRUE', 'FALSE') isadj
11 from sys.x$ksppi x, sys.x$ksppcv y
12 where x.inst_id = userenv('Instance')
13 and y.inst_id = userenv('Instance')
14 and x.indx = y.indx
15 and x.ksppinm like '%db_block_hash%'
16 order by translate(x.ksppinm, ' _', ' ');
NAME VALUE ISDEFAUL ISMOD ISADJ
--------------------------------------------- --------------- -------- -------- --------
_db_block_hash_buckets 1048576 TRUE FALSE FALSE
_db_block_hash_latches 32768 TRUE FALSE FALSE
產生的原因:
1.執行效率低下的SQL,低效的SQL語句是發生Latch:cache buffers chains 爭用的主要原因。發生在多個程式同時掃描大範圍的表或索引時。
2.出現熱塊hot block時,由於編寫SQL語句時,SQL持續掃描少數特定塊(between and ,in,not in, exists),多個會話同時執行SQL語句時,發生Latch:cache buffers chains 爭用。
【案例1 Latch:cache buffers chains爭用 】
create table t1(id int,name varchar2(10));
insert into values(1,'xiaobo');
commit;
--2.獲取t1表的第一行資料及ROWID,根據dbms_rowid包查出這行資料的檔案號、塊號
SQL> select rowid,
dbms_rowid.rowid_relative_fno(rowid) file#,
dbms_rowid.rowid_block_number(rowid) block#,
id,
name
from emm.t1
where rownum = 1; 2 3 4 5 6 7
ROWID FILE# BLOCK# ID NAME
------------------ ---------- ---------- ---------- --------------------
AAADfaAAFAAAACDAAA 5 131 1 xiaobo
注意:這裡的DBA(Data Block Address)就是由5號檔案和131號塊組成
SQL> select hladdr from x$bh where file#=5 and dbablk=131;
HLADDR
----------------
00000001D1C266D8
SQL> select addr,name,gets from v$latch_children where addr='00000001D1C266D8';
ADDR NAME GETS
---------------- -------------------------------- -----------------------------------------------
00000001D1C266D8 cache buffers chains 46
--5.再次讀取t1表的第一行資料,再次產生一次邏輯讀
SQL>select id,name from emm.t1 where rowid='AAADfaAAFAAAACDAAA';
ID NAME
-------- ------------
1 xiaobo
--6.CBC Latch的次數變為48,說明一次邏輯讀產生兩次CBC Latch
SQL> select addr,name,gets from v$latch_children where addr='00000001D1C266D8';
ADDR NAME GETS
---------------- -------------------------------- -----------------------------------------------
00000001D1C266D8 cache buffers chains 48
這裡說明一次邏輯讀要加兩次CBC Latch,一次為了加Buffer Pin,一次為了釋放Buffer Pin!
但是我不知道這裡如何透過實驗來證明,大家如果有好的建議,可以聯絡我。
使用oradebug跟蹤CBC Latch爭用事件
SQL> oradebug setmypid
Statement processed.
SQL> oradebug peek 0x1D1C266D8 4 -- 觀察CBC Latch地址為0x1D1C266D8開始之後的4位元組資訊的值為0
[1D1C266D8, 1D1C266DC) = 00000000
SQL> oradebug poke 0x1D1C266D8 4 1 --修改CBC Latch地址為0x1D1C266D8開始的4位元組資訊的值為1,相當於獲取了Latch
BEFORE: [1D1C266D8, 1D1C266DC) = 00000000 --修改前的值
AFTER: [1D1C266D8, 1D1C266DC) = 00000001 --修改後的值
--7. 再開一個新的會話,會話號為768
SQL> conn / as sysdba
Connected.
SQL> select sid from v$mystat where rownum=1;
SID
----------
768
--8.在新會話768下再查詢T1表的第一行,我觀察到不會堵塞。但是我看網上有些網友寫的部落格說這裡會產生堵塞。
這樣的說法是不正確的。原因我會做完下個實驗給大家解釋,這裡多說一句,大家看到網上的一些技術文章,一定
要自己動手做實驗。如果發現和文章說明的不一樣,一定要查閱資料。一直到搞清楚。
SQL>select id,name from emm.t1 where rowid='AAADfaAAFAAAACDAAA';
ID NAME
-------- ------------
1 xiaobo
--9.我們回到oradebug的會話,這次我們不是使用select語句,而使用update語句來獲取latch
SQL> update emm.t1 set id=2 where rowid='AAADfaAAFAAAACDAAA';
1 row updated.
--10.再次使用oradebug模擬獲取latch
SQL> oradebug setmypid
Statement processed.
SQL> oradebug poke 0x1D1C266D8 4 1
BEFORE: [1D1C266D8, 1D1C266DC) = 00000000
AFTER: [1D1C266D8, 1D1C266DC) = 00000001
--11.回到剛才768會話下,查詢T1表的第一行,這時我觀察到產生了堵塞
SQL>select id,name from emm.t1 where rowid='AAADfaAAFAAAACDAAA';
--12.我們再開第三個會話,檢視會話號768的等待事件,我們看到產生了CBC Latch的等待事件
SQL> select sid,event,p1raw,p2raw,p3raw from v$session where sid=768;
SID EVENT P1RAW P2RAW P3RAW
---------------- ------------------------------------- ------------------------- --------------------------- -------
768 latch: cache buffers chains 00000001D1C266D8 00000000000000B1 00
最後在第一個會話中釋放lacth
SQL> oradebug poke 0x1D1C266D8 4 0
BEFORE: [1D1C266D8, 1D1C266DC) = 00000001
AFTER: [1D1C266D8, 1D1C266DC) = 00000000
總結:
在獲取保護hash bucket的cache buffers chains latch時,如果是讀取工作(select),就以shared模式獲
得(這也是我們剛才在實驗中select時沒有產生爭用的原因)。如果是修改工作(update),就以exclusive模式
獲得。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12798004/viewspace-1818231/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- latch:library cache lock等待事件事件
- 33、buffer_cache_3(redo的產生、LRBA、buffer cache裡的等待事件)事件
- DB BUFFER LRU 列表的latch等待
- 【BUFFER】Oracle buffer cache之 latch 學習記錄Oracle
- latch等待事件彙總事件
- Latch free等待事件(轉)事件
- Latch free等待事件二(轉)事件
- Latch free等待事件四(轉)事件
- Latch free等待事件三(轉)事件
- 【等待事件】library cache pin事件
- Buffer Cache以及buffer busy waits/gc相關事件AIGC事件
- [異常等待事件latch undo global data]分析事件
- buffer busy wait 等待事件說明(轉)AI事件
- 【TUNE_ORACLE】等待事件之“buffer busy waits”Oracle事件AI
- 【TUNE_ORACLE】等待事件之“library cache pins”Oracle事件
- 【TUNE_ORACLE】等待事件之“library cache lock”Oracle事件
- [20211229]再論19c latch free等待事件分析.txt事件
- [20211031]18c row cache mutext等待事件探究.txtMutex事件
- IO之核心buffer----"buffer cache"
- Oracle Cache Buffer ChainsOracleAI
- [重慶思莊每日技術分享]-free buffer waits 等待事件AI事件
- XTTS全備開啟BCT後等待事件 block change tracking buffer spaceTTS事件BloC
- [20210512]shared pool latch與library cache latch的簡單探究.txt
- [20190319]shared pool latch與library cache latch的簡單探究.txt
- 【Cache】將常用的“小表”快取到Buffer Cache快取
- buffer與cache的區別
- Linux Buffer/Cache 的區別Linux
- Solidity事件,等待事件Solid事件
- [20240827]分析為什麼出現library cache lock等待事件2.txt事件
- [20240828]分析為什麼出現library cache lock等待事件5.txt事件
- 【TUNE_ORACLE】等待事件之等待事件類別Oracle事件
- PostgreSQL DBA(89) - Linux(Buffer vs Cache)SQLLinux
- Linux記憶體、Swap、Cache、BufferLinux記憶體
- 清理buffer/cache/swap的方法梳理
- 當刪除oracle資料庫user時發生row cache lock 等待事件Oracle資料庫事件
- oracle常見異常等待——latch處理思路Oracle
- [20190423]簡單測試latch nowilling等待模式.txt模式
- Cache 和 Buffer 的區別在哪裡?
- Cache 和 Buffer 有什麼區別?