領導毛主席在《在魯迅藝術學院的講話》中說過這樣一段話:俗話說,走馬看花不如駐馬看花,駐馬看花不如下馬看花,我 希望你們都要下馬看花。是的,有時候技術學到一定階段,很多細節知識確實需要我們 窮波討源,細緻的研究,今天和大家聊得是alert 日誌中出現Private strand flush not c... ...
--Lerning Content :Oracle 下馬觀花看redo--Author :如人飲水冷暖自知--版權所有 :首發於ORA-600團隊微信公眾號:
《Oracle 藍蓮花》:轉載請註明出處以及作者
技術分享交流QQ群:851604218
2019年3月中旬,有技術分享交流課程,歡迎加群探討
-----------------------------------------
引言
下馬看花-redo
領導毛主席在《在魯迅藝術學院的講話》中說過這樣一段話:俗話說,走馬看花不如駐馬看花,駐馬看花不如下馬看花,我 希望你們都要下馬看花。是的,有時候技術學到一定階段,很多細節知識確實需要我們 窮波討源,細緻的研究,今天和大家聊得是alert 日誌中出現Private strand flush not complete提示,這提示背後的故事.
1
背景介紹
截圖1為簡單的QQ溝通
初步瞭解DBA排錯思路和現場問題情況
截圖2為alert日誌中具體的信息提示
截圖3為前臺應用給出的另一個報錯信息
AWR報告信息提示:
1.對於log file switch (checkpoint incomplete)等待事件,容易誤導DBA的排查思路,awr報告里該等待事件平均等待 601.22毫秒,占用當前dbtime 31%,同時db cpu占用dbtime的比例達到41%。這裡我們不妨分析這個等待事件產生的成因,log file switch (checkpoint incomplete)指的是當redo需要向下一組redo group切換的時候,發現下組日誌是active活動狀態的,簡單的說就是下組日誌中對應的一些buffer cache中的臟塊壓根沒有寫入到數據文件中,因此必須等待這些dirty block被flush完畢 後,才可以復用下一組redo group
2.既然是把dirty block flush到datafile,那麼自然是dbwn的工作,實際我們需要更多關註的是dbwn這個進程的寫io負載情 況,那麼awr里有8.3g的控制文件io負載是為什麼,其實是DBW本身的io問題導致 LGWR不斷查詢control 文件獲取redo 狀態,獲 取狀態最根本的目的就是想知道究竟redo切換是否成功,所以後臺產生大量控制文件io操作。
3.在以前的文章中我們分享過log file sync等待事件,寫redo很慢,從而導致gc buffer busy acquire /release 等待事件,其 實這個就比較方便定位,只要我們做了addm,可以看到諸如如下的提示:Waits on event “log file sync” were the cause of significant database wait on “gc buffer busy” when releasing a data block. Waits on event“log file sync” in this instance can cause global cache contention on remote instances,那麼基本可以確認gc buffer busy的源頭是log file sync(雖然本質上不是),那麼優先解決log file sync的問題。
oracle 9i時代,企業業務數據還沒井噴,無論是事務還是日誌生成量都相對較少,那個年代沒有所謂大數據的概念,基本都 維持在一次變更,一條數據,一次記憶體分配即可完成的狀態,隨著企業業務數據激增,尤其oltp系統,老的redo機制已經無法滿足 高併發,大寫入量的需求,到10g版本以後oracle推出了private redo 和imu,也就是in-memory undo的機制,這樣一來,一個 進程就可以以整個事務的方式去工作,生成所有的改變向量,並將它們存入私有重做日誌緩衝區,也就是private redo log buffer 中,當事務提交時,進程將存於私有重做日誌緩衝區的記錄複製到公共的重做日誌緩衝區,這時,跟傳統的重做日誌緩衝區工作原 理保持一致,那麼寫到重做日誌文件的過程,一個進程在一個事務里只需要獲得一次公共的redo allocation latch,而不是每次變 更都要獲取一次latch。
既然是下馬看花,為了方便大家理解,我們至少要搞懂幾個事情,才能做到真正意義的賞花望月,imu機制帶來的in memory undo latch是否影響資料庫負載,是否有威脅,同時分析重做日誌文件,搞清楚redo entry都記錄了什麼,同時我們還要 分析x$kcrfstrand x$ktifp理解各種實例活動信息之間的關聯關係,這裡涉及的技術知識點比較多,由於篇幅原因,和大家分享兩個 相對重要的:
1. 關於redo方面增量的基礎結構由兩組記憶體結構組成,一組是x$kcrfstrand私有redo區域,主要處理前滾改變向量, 另一組x$ktifp imu區域,處理undo改變向量,私有redo區域裡面也包含傳統的公共重做日誌緩衝區,因此如果查詢這個固化視圖 發現有兩類不同的信息,不要擔心,是正常現象。
2. x$ktifp表示imu區域中的池個數,取決於持有事務的細節v$transaction的數組大小,它由oracle的參數 transactions設定,但是這個參數通常隨session 或者processes參數調整自動更新,基本上,池的個數預設為transactions/10,比 如transactions是1000,那麼池的個數就是100,每個池是由自己的imu latch受保護的。
3. x$ktifp中的每一條記錄在x$kcrfstrand中都有與之對應的一條私有redo記錄,不過x$kcrfstrand還會涉及其他信 息,公共的redo記錄個數由cpu_count參數決定,演算法是ceiling(1 + cpu_count/16)
4. x$kcrfstrand中的每一條私有重做記錄都由自身的redo allocation latch來保護,每一條公共的重做記錄都由傳統 的redo copy latch保護,每個cpu一個redo copy latch
根據oracle官方介紹為了減少redo allocation latch等待,在oracle 9i中,引入了log buffer的並行機制。其基本原理就 是,將log buffer劃分為多個小的buffer,這些小的buffer被成為strand(為了和之後出現的private strand區別,它們被稱之為 shared strand)。
每一個strand受到一個單獨redo allocation latch的保護。多個shared strand的出現,使原來序列化的redo buffer分配變成了並行的過程,從而減少了redo allocation latch等待。shared strand的初始數據量是由參數log_parallelism控 制的;
在10g中,該參數成為隱含參數,並新增參數_log_parallelism_max控制shared strand的最大數量; _log_parallelism_dynamic則控制是否允許shared strand數量在_log_parallelism和_log_parallelism_max之間動態變化,這裡需
要註意_log_parallelism在12c版本已經棄用
每一個shared strand的大小 = log_buffer/(shared strand數量) 關於shared strand的數