Buffer Busy Waits深入分析

n-lauren發表於2014-12-02
對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的持有時間。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22990797/viewspace-1354437/,如需轉載,請註明出處,否則將追究法律責任。

相關文章