您好,登錄后才能下訂單哦!
log file sync問題的解決是一個系統工程,除了上面一節描述的調優方式,我們看看對于其他組建是否也需要調優。例如commit本身作為一個redo record也是需要被拷貝進log buffer的,如果此時log buffer太小沒有了空間,那么豈不是也會在一定程度上影響提交的效率,再如,Lgwr在刷新日志前,需要確認所有分配過空間的buffer都已經拷貝結束,如果發現還有進程在持有redo copy latch就說明還有進程正在往log buffer拷貝日志,那么這個時候也會導致提交變慢。
LOG BUFFER 的調優
10G以后,LOG BUFFER一般情況下已經比較大,一般為1到多個granules大小,除非你看到了比較多的log buffer space等待事件,否則不需要調整log buffer的大小。
redo相關latch的調優
l redo copy latch:僅僅用來跟蹤是否有進程正在往log buffer里拷貝數據。lgwr在真正開始寫之前,必須等待相關的進程拷貝完畢,在此期間,lgwr會等待LGWR wait for redo copy等待。可以同時向log buffer里進行拷貝的進程的數量由_log_simultaneous_copies決定。除非觀察到明顯的redo copy latch等待,否則保持默認值。
l redo allocation latch:保護進程在redo buffer里分配空間時使用,保證各個進程間彼此分配的空間不重疊。9.2版本以前由于redo allocation latch只有一把,因此比較容易引起此latch的真用,9.2版本以后,根據主機CPU的多少,log buffer已經被拆分成多個子LOG BUFFER,每個子buffer 都有有對應的redo allocation latch,很大程度上緩解了redo allocatoin latch的爭用,除非看到了明顯的redo allocation latch的爭用,否則不用調整log buffer的數量。10G以后,私有redo和IMU的出現,每一個私有redo都由一個私有的redo allocation latch保護,進一步降低了redo allocation latch的爭用。
redo writing latch:這個latch保護的是一個標志位,進程獲取這個latch后,修改標志位,比如把0改為1,代表lgwr正在寫,這樣后續的提交進程,獲得這個latch后讀取標志位,就知道當前LGWR是不是正在寫了,避免了很多不需要的重復通知。
一般是不需要的,除非他們相關的等待已經引起了你的注意,而且ORACLE各個版本也一直在優化相關的latch的獲取和釋放,比如redo allocation latch,這一塊已經做的非常高效了。
10G之前,在事務做提交的時候,必須等待Lgwr刷日志完成才能繼續做其它事,也就是說必須符合事務持久化的條件,可能學過其他數據庫的同學學ORACLE的時候怪怪的,因為像MYSQL、MONGODB等數據庫都支持對日志的異步刷新,我想之所以ORACLE這么晚才推出這一功能,主要還是使用ORACLE的客戶都是金融、證券等行業巨多,這些行業對于數據的丟失是零容忍的,因此他們對此并無需求,直到10GR1,ORACLE公司才默默的推出了一個參數:commit_logging,這個參數可以實現讓事務在提交時,并不同步刷新日志,而是在合適的時候去觸發,這個參數可以有四種組合:
commit write [batch|immediate][wait|nowait]
10GR2版本發布的時候,這個參數被拆成了2個參數,commit_logging,commit_write,個人認為10GR2拆分后的參數,更能準確表達參數的意圖。我們先著重的看下commit_write這個參數,它的參數值可以為wait/nowait,代表:前臺進程在進行事務提交的時候,通不通知LGWR去刷新日志。wait為通知,前臺進程會等待log file sync。nowait為不通知,僅僅等待其他操作觸發lgwr去寫日志(如3秒,1M大小,1/3滿)。如果你的業務對數據的一致性的要求不高,對ACID的D沒有要求,為了提高事務數、提高性能,你可以選擇commit_write為nowait方式。而在10G以前,ACID的D是必須滿足的,也就是說,前臺進程在提交的時候,必須要等待LOG FILE SYNC,等待LGWR刷新日志到磁盤。我們再來看下commit_logging參數,參數可以選擇的值有batch/immediate,這個參數極其容易引起人的誤解,讓人誤以為batch的含義是,控制著事務是否以group commit的方式打包提交,而immediate含義是讓事務一個個的提交,一次提交刷新一次log buffer,但實時不是這樣的!
immediate與batch相比,commit的改變向量(修改回滾段頭的事務槽)將作為stand alone(單獨的)的redo record產生,跟9I的commit記錄日志的方式是一樣的。batch 模式下commit改變向量的記錄方式是合并進事務產生的change vector里,作為一個redo record,這個batch模式依賴是否使用私有redo和IMU,如果私有redo和IMU被關閉的情況下,batch的設置也就沒了作用。
我們對insert into a values(1111);commit;來進行dump log file,闡述一下batch/immediate方式的區別 :
DUMP LOG FILE:啟用私有redo和IMU,設置commit_logging為immediate,commit的日志作為單獨的redo record產生,一共2條redo record,第二個redo record為commit產生的,見加粗部分(OP:5.4,代表為UNDO段頭的修改)
REDO RECORD - Thread:1 RBA: 0x00044d.00000002.0010 LEN: 0x0230 VLD: 0x05 |
DUMP LOG FILE:啟用私有redo和imu,設置commit_logging為batch,commit作為一個改變向量合并進了事務的redo record里,作為一條redo record,change #3為commit產生的。
REDO RECORD - Thread:1 RBA: 0x00044d.00000002.0010 LEN: 0x0230 VLD: 0x05 |
個人感覺commit_logging參數的作用不大,可能有助于減少ACID的異常時間,對日志量的size在batch模式下有輕微的減少。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。