Buffer Busy Waits深入分析
對Buffer Busy Waits進行了次深入的分析,得到結論如下:
一、相容模式:
10G後的Buffer Busy Waits已經和以前大不一樣了。不再是以前的讀、寫互相阻塞,或寫、寫互相阻塞。也不是有些網友說的讀、寫不阻塞,只有寫、寫阻塞。
真實的Buffer Busy Waits,有如下兩種情況:
(1)、兩個程式一同寫一個Buffer,這是寫、寫阻塞。
(2)、一個程式在寫一個Buffer,另一個程式讀。讀的程式會有等待。這是寫阻塞讀。
現在,Buffer Busy Waits,只有這兩種情況了。
有人說,如果一個程式先開始讀一個Buffer,另一個程式又要寫一個Buffer,這種情況下Oracle如何處理?讀會阻塞寫嗎?答案是,不會。寫的操作可以不需等待的馬上開始,而正在進行的讀操作,則會中止開始等待Buffer Busy Waits。這就是為什麼在Buffer busy waits升高時,查詢SQL語句,等待Buffer busy waits的大多數會話都是Select,很少有DML。因為DML不會被Select阻塞,只有DML間會互相阻塞。關於一點,做個簡單的測試就可以證明:
在會話1執行如下指令碼:
declare
j number;
begin
for i in 1..3000000 loop
select id into j from a1 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
end;
/
反覆讀取某一行。
在會話2執行如下指令碼:
begin
for i in 1..300 loop
update a1 set id=id+0 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
commit;
end;
/
然後在V$SESSION_EVENT中檢視兩個Session的Buffer busy waits等待。
會話1反覆查詢一行,會話2反覆更新同一行300次,兩個會話應該各有少許的Buffer busy waits,對吧。
但實際情況不是這樣的。會話2一般不會有,只有會話1會有Buffer busy wait等待。
這就是寫阻塞讀、讀在大部分情況下,不會阻塞寫。當然,除了這種證明方法外,還有更加精確的方法,證明寫阻塞讀、讀不阻塞寫,我放在後面深入部分。
二、減少Buffer busy waits的另類方法
我在前一篇文章中,提到從巨集觀上減少Buffer busy waits等待的另一種方法,就是加快日誌檔案的寫速度,使用更快的裝置,放存Redo檔案。原理是什麼呢:
程式在Buffer Cache中的某個Buffer加的鎖,我稱之為Buffer Pin。程式修改一個Buffer的過程,可以粗略的描述如下:
(1)、加Cache buffers chains latch(下文中簡稱為CBC Latch)
(2)、加Buffer Pin
(3)、釋放CBC Latch。
(4)、將Redo資訊拷貝到共享池的公有Redo區,或Log Buffer中。
(5)、修改Buffer中的內容
(6)、加CBC Latch
(7)、釋放Buffer Pin
(8)、釋放CBC Latch
1至3步,加CBC Latch,是為了加Buffer Pin。6至8步的CBC Latch,是釋放Buffer pin。
在加了Buffer Pin之後,主要要做的事情有兩個,一個是修改Buffer中的內容。另一個,是拷貝Redo資訊。
減少Buffer busy waits,其實就是縮短Buffer Pin的持有時間。縮短Buffer Pin的持有時間,我們可以做的事情有兩個,一個是加快第5步,“修改Buffer中的內容”。或者,是第4步,拷貝Redo資訊。在第5步,Oracle修改Buffer中內容,使用的是memcpy函式,這一步沒什麼好優化的了。但第4步拷貝Redo資訊,還是可以調優的。在一定條件下,前臺程式要將Redo資訊直接拷貝到Log Buffer,而不是共享池中的私有Redo區。此時,如果Log Buffer中沒有空間,遇到Log Buffer Space等待,前臺程式要呼叫LGWR重新整理Log Buffer。一旦出現這種情況,Buffer Pin的持有時間不得不變的很長,直到Log buffer中有空間了,拷貝Redo資訊結束,前臺程式修改完Buffer中的內容。然後才會釋放Buffer pin。
因此,如果我們可以保證Log Buffer中總是有空間可用,就可以減少Log Buffer Space,從而減少前臺程式呼叫LGWR的次數,從而在某些時候減少Buffer Pin的持有時間。
一、相容模式:
10G後的Buffer Busy Waits已經和以前大不一樣了。不再是以前的讀、寫互相阻塞,或寫、寫互相阻塞。也不是有些網友說的讀、寫不阻塞,只有寫、寫阻塞。
真實的Buffer Busy Waits,有如下兩種情況:
(1)、兩個程式一同寫一個Buffer,這是寫、寫阻塞。
(2)、一個程式在寫一個Buffer,另一個程式讀。讀的程式會有等待。這是寫阻塞讀。
現在,Buffer Busy Waits,只有這兩種情況了。
有人說,如果一個程式先開始讀一個Buffer,另一個程式又要寫一個Buffer,這種情況下Oracle如何處理?讀會阻塞寫嗎?答案是,不會。寫的操作可以不需等待的馬上開始,而正在進行的讀操作,則會中止開始等待Buffer Busy Waits。這就是為什麼在Buffer busy waits升高時,查詢SQL語句,等待Buffer busy waits的大多數會話都是Select,很少有DML。因為DML不會被Select阻塞,只有DML間會互相阻塞。關於一點,做個簡單的測試就可以證明:
在會話1執行如下指令碼:
declare
j number;
begin
for i in 1..3000000 loop
select id into j from a1 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
end;
/
反覆讀取某一行。
在會話2執行如下指令碼:
begin
for i in 1..300 loop
update a1 set id=id+0 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
commit;
end;
/
然後在V$SESSION_EVENT中檢視兩個Session的Buffer busy waits等待。
會話1反覆查詢一行,會話2反覆更新同一行300次,兩個會話應該各有少許的Buffer busy waits,對吧。
但實際情況不是這樣的。會話2一般不會有,只有會話1會有Buffer busy wait等待。
這就是寫阻塞讀、讀在大部分情況下,不會阻塞寫。當然,除了這種證明方法外,還有更加精確的方法,證明寫阻塞讀、讀不阻塞寫,我放在後面深入部分。
二、減少Buffer busy waits的另類方法
我在前一篇文章中,提到從巨集觀上減少Buffer busy waits等待的另一種方法,就是加快日誌檔案的寫速度,使用更快的裝置,放存Redo檔案。原理是什麼呢:
程式在Buffer Cache中的某個Buffer加的鎖,我稱之為Buffer Pin。程式修改一個Buffer的過程,可以粗略的描述如下:
(1)、加Cache buffers chains latch(下文中簡稱為CBC Latch)
(2)、加Buffer Pin
(3)、釋放CBC Latch。
(4)、將Redo資訊拷貝到共享池的公有Redo區,或Log Buffer中。
(5)、修改Buffer中的內容
(6)、加CBC Latch
(7)、釋放Buffer Pin
(8)、釋放CBC Latch
1至3步,加CBC Latch,是為了加Buffer Pin。6至8步的CBC Latch,是釋放Buffer pin。
在加了Buffer Pin之後,主要要做的事情有兩個,一個是修改Buffer中的內容。另一個,是拷貝Redo資訊。
減少Buffer busy waits,其實就是縮短Buffer Pin的持有時間。縮短Buffer Pin的持有時間,我們可以做的事情有兩個,一個是加快第5步,“修改Buffer中的內容”。或者,是第4步,拷貝Redo資訊。在第5步,Oracle修改Buffer中內容,使用的是memcpy函式,這一步沒什麼好優化的了。但第4步拷貝Redo資訊,還是可以調優的。在一定條件下,前臺程式要將Redo資訊直接拷貝到Log Buffer,而不是共享池中的私有Redo區。此時,如果Log Buffer中沒有空間,遇到Log Buffer Space等待,前臺程式要呼叫LGWR重新整理Log Buffer。一旦出現這種情況,Buffer Pin的持有時間不得不變的很長,直到Log buffer中有空間了,拷貝Redo資訊結束,前臺程式修改完Buffer中的內容。然後才會釋放Buffer pin。
因此,如果我們可以保證Log Buffer中總是有空間可用,就可以減少Log Buffer Space,從而減少前臺程式呼叫LGWR的次數,從而在某些時候減少Buffer Pin的持有時間。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22990797/viewspace-1354437/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle Buffer Busy WaitsOracleAI
- 【等待事件】buffer busy waits事件AI
- Buffer busy waits/read by other sessionAISession
- buffer busy waits你誤解了嗎?AI
- Buffer Cache以及buffer busy waits/gc相關事件AIGC事件
- buffer busy waits引起的會話突增AI會話
- oracle buffer busy waits等待的含義OracleAI
- buffer busy waits 平均等待時間AI
- buffer cache實驗7-buffer busy waits-完成AI
- GC Buffer Busy Waits in RAC: Finding Hot BlocksGCAIBloC
- 【TUNE_ORACLE】等待事件之“buffer busy waits”Oracle事件AI
- Buffer Busy Waits是怎麼產生的?AI
- update/select也可能產生buffer busy waits。AI
- [摘錄]Oracle Wait Interface之Buffer busy waits事件OracleAI事件
- Oracle Dba必須瞭解的buffer busy waits等待OracleAI
- 等待事件_buffer_busy_waits_and_read_by_other_session(1)事件AISession
- 等待事件_buffer_busy_waits_and_read_by_other_session(2)事件AISession
- 等待事件_buffer_busy_waits_and_read_by_other_session(3)事件AISession
- 等待事件_buffer_busy_waits_and_read_by_other_session(4)事件AISession
- 效能調整一則:buffer busy waits導致主要issueAI
- [20161214]關於Buffer Busy Waits.txtAI
- [20150122]buffer busy waits特例.txtAI
- buffer busy waits與rac cluster wait之間的聯絡AI
- buffer busy waits, latch cache buffers chains, read by other session區別AISession
- gc buffer busyGC
- Oracle Free Buffer WaitsOracleAI
- buffer busy wait 解析AI
- wait event:gc buffer busyAIGC
- gc buffer busy的優化GC優化
- Buffer Busy Wait小結AI
- zt_buffer busy waitAI
- Oracle優化案例-Bug 5552515引起的buffer busy waits和表物理讀(二十四)Oracle優化AI
- gc buffer busy的最佳化GC
- 等待模擬-BUFFER BUSY WAITAI
- buffer busy wait 的深度剖析AI
- buffer cache實驗8-free buffer waits-完成AI
- gc buffer busy acquire問題處理GCUI
- rac 遭遇GC BUFFER BUSY 處理思路GC