Checkpoint Incomplete

用戶大叫。他們說他們的屏幕凍結了好幾秒鐘,而且它們在應用程序中的位置也沒有關係。

我運行我的Oracle基於時間的分析報告,面對的是Oracle等待事件-日誌文件切換檢查點不完整。我還注意到,Oracle進程比日誌文件切換時間消耗更多的CPU時間!

這意味著什麼,可以做什麼,我應該如何前進?本文的目的是如何解決Oracle日誌文件切換檢查點未完成等待事件的情況。

Listening To The Users

啊,是的。音樂在我耳邊。正如我所提到的,應用程序用戶感到不高興……真的很沮喪。當他們將工作保存在應用程序中的任何位置時,其屏幕最多可能會凍結20秒。但是對他們來說似乎是隨機的。他們經驗中唯一一致的部 分是凍結僅在他們保存工作時發生。

當我聽到這樣的故事時,我立即想到了封鎖還是鎖定。

該鎖可以是表級或行級鎖。但是無論如何,它都與關係對像有關。我希望相關的等待事件將是TM或TX排隊等待。

當用戶在保存工作時遇到死屏時,而與排隊等待無關,則可能是Oracle重做特定的,而不是與應用程序對象(例如表)相關的。這就像是在阻止用戶保存工作之後阻止Oracle流程前進的某種事情。與Oracle檢查點相關的等 待事件非常適合這種情況。

看到基於Oracle時間的報告後,我將知道它是與鎖定有關還是與阻塞有關。而且,當我著眼於操作系統情況和更多的SQL觀點時,我應該擁有設計多種解決方案所需的一切。所以,讓我們開始吧!

什麼是日誌文件切換(檢查點未完成)事件?

什麼是Oracle數據庫日誌文件切換檢查點未完成等待事件?我將盡我所能盡快解釋這一點。當Oracle會話更改緩衝區高速緩存中的Oracle緩衝區時,其進程會將足夠的重做信息複製到重做緩衝區中。由於多種原因,日誌編 寫器會將其重做從重做緩衝區寫入在線重做日誌文件中。聯機重做日誌文件一個接一個地連接到下一個,從而形成一個閉環。當日誌寫入器正在寫入聯機重做日誌時,最終它將填滿,並且日誌寫入器必須切換到下一個聯機 重做日誌,然後才能開始寫入。該開關是等待事件“日誌文件開關(檢查點未完成)”中的“日誌文件開關”。

當日誌編寫器想要切換到下一個聯機重做日誌時,將啟動檢查點。此檢查點是等待事件“日誌文件切換(檢查點不完整)”中的“檢查點”。

Oracle會話正在等待,實際上是凍結的,正在等待檢查點完成。

這種類型的檢查點要求將所有與切換到重做日誌中與重做相關的更改緩衝區寫入其關聯的Oracle數據庫文件(DBF)中。這個等待是絕對必要的。

原因如下:假設此下一個重做日誌包含已提交的數據,並且此已提交的數據當前僅駐留在Oracle的緩衝區高速緩存中。因此,如果日誌編寫者要切換到下一個聯機重做日誌,然後覆蓋已提交的內容,那麼實例失敗將導致緩 衝區高速緩存消失thin……提交的數據將丟失。確實是DBA的噩夢,而Oracle將非常努力地嘗試這種情況,永遠不會允許。

數據庫寫程序完成後,將所有與檢查點相關的緩衝區寫入其DBF文件中,並完成一些家務活,現在該檢查點已完成。並且允許日誌編寫器完成日誌切換並開始寫入下一個聯機重做日誌。

一旦日誌編寫者完成了將用戶的重做寫入在線重做日誌文件,他們的提交就基本上完成了,他們可以繼續進行工作。

從技術角度來看非常酷的東西!但是讓我們回到解決問題上來...

獲取性能基準

在繼續診斷情況之前,我們需要創建一個基準。這是我的想法:我需要知道我的表現是否做得很好。我想對此進行數字量化。我要記錄工作量,等待事件情況,以及在這種情況下的聯機重做日誌切換率。我將詳細說明每個。

基準:日誌文件切換率

通常,在日誌文件切換檢查點不完整的情況下,聯機重做日誌每隔幾分鐘甚至每隔幾秒鐘切換一次!一種獲得開關速率的方法是計時一分鐘內發生多少次開關。至少採集三個樣本。如果它們的差異超過每分鐘5個開關,請再進行一些採樣。

這是我的操作方式:

SQL> show parameter background_dump_dest

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest                 string      /home/oracle/base/diag/rdbms/p
                                                 rod30/prod30/trace
SQL> !tail -f /home/oracle/base/diag/rdbms/prod30/prod30/trace/alert*log | grep "advanced to log sequence"
Thread 1 advanced to log sequence 335098 (LGWR switch)
Thread 1 advanced to log sequence 335099 (LGWR switch)
Thread 1 advanced to log sequence 335100 (LGWR switch)
Thread 1 advanced to log sequence 335101 (LGWR switch)
...

在我的系統上,我收集了三個一分鐘的樣本。每分鐘37、38和34個日誌開關的值。因此,平均為36.33開關/分鐘。我將記錄下來,因為它是我基準的一部分。實施解決方案時,我希望日誌切換速率會大大降低。

基準:等待事件百分比

參考上面的總時間報告(ttpctx.sql)報告,從總時間角度(cpu和非空閒等待時間)來看,日誌文件切換檢查點不完整時間佔總時間的29.16%。從僅等待時間的角度來看,事件時間佔所有等待時間的53.56%。

實施解決方案時,我希望日誌文件開關檢查點不完整的等待時間百分比會大大降低。 基準:工作負載率

通常,我會選擇一些用戶和時間來提交事務。如果不可能,我將選擇與Oracle工作負載相關的統計信息,以封裝緩衝區更改。一種完美的統計數據是,數據庫塊更改。我真正想要的是變化率,例如每秒的塊變化。

這是我如何在60秒的間隔內獲得此統計信息。

set serveroutput on
variable bogus_v number;
begin
   select value
   into   :bogus_v
   from   v$sysstat
   where  name='db block changes';

   dbms_lock.sleep(60);

   select (value-:bogus_v)/60
   into   :bogus_v
   from   v$sysstat
   where  name='db block changes';

   dbms_output.put_line('block changes per sec = '||round(:bogus_v,2));
end;
/

在我的系統上,我運行了上述腳本3次。該塊每秒更改一次,其中13680.85、13223.25和11930.93。因此,平均值為每秒12945.01個塊更改。

當我實施解決方案時,我希望塊更改率會大大提高。我希望毫無疑問,系統正在處理更多的工作。如果我不確定我選擇的工作負載統計信息可以使我證明這一點,那麼我將找到另一個統計信息或使用多個統計信息。

基準摘要

我現在已經完成了基準性能統計數據的收集。這是我們收集的:

實施選定的解決方案後,我將再次收集性能統計信息……希望能看到重大改進! 喘口氣

到目前為止,我們一直在認真聽取用戶的意見,收集了基準性能統計信息,并快速了解了Oracle的時序情況(@ ttpctx.sql)。這是我的出發點。

接下來,我將仔細研究Oracle,操作系統以及應用程序。對於這些子系統中的每一個,我將得出至少一個解決方案,對它們進行排名並選擇一個要實施的解決方案,然後實施該方案,然後重新運行我的基線,希望能看到一個驚人的改進。

Thanks for reading and enjoy your work!

désert/Oracle/Checkpoint (last edited 2020-04-04 12:32:11 by merlin)