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