如下圖一,假設有個進程A正在讀10號文件的11號數據塊,此時又有一個進程B准備寫該數據塊。首先獲取cbc latch然后復制內存中的10號文件11號塊並新增一個buffer header(bh),並把原來的bh中status改為xcur,復制完成后釋放cbc latch。然后如圖二,獲得cbc latch修改原塊狀態為CR,復制塊狀態為XCUR並把buffer pin修改為X,然后可以釋放latch cbc,然后進程B 可以修改該數據塊,此時如果進程c要讀該數據塊,那么進程c就要進行等待,等待事件即buffer busy wait。附實驗證明
圖一:
圖二:
實驗一:
會話一: SQL> select distinct sid from v$mystat; SID ---------- 853 會話二: SQL> select distinct sid from v$mystat 2 ; SID ---------- 1713 會話三: SQL> select sid,event,total_waits,total_timeouts,time_waited_micro/100,time_waited_micro/total_waits/100 2 from v$session_event where sid in (853,1713) and event in ('buffer busy waits'); no rows selected 會話一進行讀數據塊: declare j number; begin for i in 1..3000000 loop select id into j from ye where rowid='AAAWt/AAKAAAAHaACV'; end loop; end; / 會話二進行寫數據塊: begin for i in 1..300 loop update ye set id=id+0 where rowid='AAAWt/AAKAAAAHaACV'; commit; end loop; end; / 會話三查詢等待事件為853會話等待: SID EVENT TOTAL_WAITS TOTAL_TIMEOUTS TIME_WAITED_MICRO/100 TIME_WAITED_MICRO/TOTAL_WAITS/100 ---------- ---------------------------------------- ----------- -------------- --------------------- --------------------------------- 853 buffer busy waits 81 0 30.32 .374320988 上述步驟不變,將會話二中更新數據增到1000次 在會話三中發現也出現了3次buffer busy wait: SQL> / SID EVENT TOTAL_WAITS TOTAL_TIMEOUTS TIME_WAITED_MICRO/100 TIME_WAITED_MICRO/TOTAL_WAITS/100 ---------- ---------------------------------------- ----------- -------------- --------------------- --------------------------------- 853 buffer busy waits 499 0 238.01 .476973948 1713 buffer busy waits 3 0 1.67 .556666667 這3次等待其實發生在undo block上,當會話853構造cr塊是需要在undo上加上共享模式buffer bin,在會話1713寫block需要向undo寫入前印象,因此需要等待853構造完cr塊。
會話1713分別改為:
begin
for i in 1..60000 loop
update ye set id=id+0 where rowid='AAAWt/AAKAAAAHaACV';
if mod(i,500)=0 then
commit;
end if;
end loop;
commit;
end;
/
begin
for i in 1..60000 loop
update ye set id=id+0 where rowid='AAAWt/AAKAAAAHaACV';
commit;
end loop;
commit;
end;
/
會話三的結果:
SQL> select sid,event,total_waits,total_timeouts,time_waited_micro/100,time_waited_micro/total_waits/100
2 from v$session_event where sid in (853,1713) and event in ('buffer busy waits');
SID EVENT TOTAL_WAITS TOTAL_TIMEOUTS TIME_WAITED_MICRO/100 TIME_WAITED_MICRO/TOTAL_WAITS/100
---------- ---------------------------------------- ----------- -------------- --------------------- ---------------------------------
853 buffer busy waits 12923 0 4291.97 .332118703
1713 buffer busy waits 1448 0 567.66 .392030387
SQL> /
SID EVENT TOTAL_WAITS TOTAL_TIMEOUTS TIME_WAITED_MICRO/100 TIME_WAITED_MICRO/TOTAL_WAITS/100
---------- ---------------------------------------- ----------- -------------- --------------------- ---------------------------------
853 buffer busy waits 32471 0 11886.11 .366053094
1713 buffer busy waits 1568 0 605.15 .3859375
說明長事務會等待讀構造cr塊比短事務等待讀構造cr塊更久