• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Just enjoy programming

            Oracle Redo Log 機(jī)制 小結(jié)(轉(zhuǎn)載)

            Oracle 的Redo 機(jī)制DB的一個(gè)重要機(jī)制,理解這個(gè)機(jī)制對(duì)DBA來(lái)說(shuō)也是非常重要,之前的Blog里也林林散散的寫(xiě)了一些,前些日子看老白日記里也有說(shuō)明,所以結(jié)合老白日記里的內(nèi)容,對(duì)oracle 的整個(gè)Redo log 機(jī)制重新整理一下。

             

            一.Redo log 說(shuō)明

            Oracle 的Online redo log 是為確保已經(jīng)提交的事務(wù)不會(huì)丟失而建立的一個(gè)機(jī)制。 因?yàn)檫@種健全的機(jī)制,才能讓我們?cè)跀?shù)據(jù)庫(kù)crash時(shí),恢復(fù)數(shù)據(jù),保證數(shù)據(jù)不丟失。

             

            1.1 恢復(fù)分類(lèi)

            恢復(fù)分兩種:

            (1)    Crash recovery

            (2)    Media recovery

             

            這兩種的具體說(shuō)明,參考:

            Oracle 實(shí)例恢復(fù)時(shí) 前滾(roll forward) 后滾(rollback) 問(wèn)題

            http://blog.csdn.net/tianlesoftware/article/details/6286330

             

            這兩種的區(qū)別是:

            (1)    Crash Recovery 是在啟動(dòng)時(shí)DB 自動(dòng)完成,而MediaRecovery 需要DBA 手工的完成。

            (2)    Crash Recovery 使用online redo log,Media Recovery 使用archived log 和 online redo log。

            (3)    Media Recovery 可能還需要從備份中Restore datafile。

             

            1.2 Crash Recovery 過(guò)程

                   當(dāng)數(shù)據(jù)庫(kù)突然崩潰,而還沒(méi)有來(lái)得及將buffer cache里的臟數(shù)據(jù)塊刷新到數(shù)據(jù)文件里,同時(shí)在實(shí)例崩潰時(shí)正在運(yùn)行著的事務(wù)被突然中斷,則事務(wù)為中間狀態(tài),也就是既沒(méi)有提交也沒(méi)有回滾。這時(shí)數(shù)據(jù)文件里的內(nèi)容不能體現(xiàn)實(shí)例崩潰時(shí)的狀態(tài)。這樣關(guān)閉的數(shù)據(jù)庫(kù)是不一致的。

             

                   下次啟動(dòng)實(shí)例時(shí),Oracle會(huì)由SMON進(jìn)程自動(dòng)進(jìn)行實(shí)例恢復(fù)。實(shí)例啟動(dòng)時(shí),SMON進(jìn)程會(huì)去檢查控制文件中所記錄的、每個(gè)在線的、可讀寫(xiě)的數(shù)據(jù)文件的END SCN號(hào)。

                   數(shù)據(jù)庫(kù)正常運(yùn)行過(guò)程中,該END SCN號(hào)始終為NULL,而當(dāng)數(shù)據(jù)庫(kù)正常關(guān)閉時(shí),會(huì)進(jìn)行完全檢查點(diǎn),并將檢查點(diǎn)SCN號(hào)更新該字段。

                   而崩潰時(shí),Oracle還來(lái)不及更新該字段,則該字段仍然為NULL。當(dāng)SMON進(jìn)程發(fā)現(xiàn)該字段為空時(shí),就知道實(shí)例在上次沒(méi)有正常關(guān)閉,于是由SMON進(jìn)程就開(kāi)始進(jìn)行實(shí)例恢復(fù)了。

             

            1.2.1 前滾

                   SMON進(jìn)程進(jìn)行實(shí)例恢復(fù)時(shí),會(huì)從控制文件中獲得檢查點(diǎn)位置。于是,SMON進(jìn)程到聯(lián)機(jī)日志文件中,找到該檢查點(diǎn)位置,然后從該檢查點(diǎn)位置開(kāi)始往下,應(yīng)用所有的重做條目,從而在buffer cache里又恢復(fù)了實(shí)例崩潰那個(gè)時(shí)間點(diǎn)的狀態(tài)。這個(gè)過(guò)程叫做前滾,前滾完畢以后,buffer cache里既有崩潰時(shí)已經(jīng)提交還沒(méi)有寫(xiě)入數(shù)據(jù)文件的臟數(shù)據(jù)塊,也還有事務(wù)被突然終止,而導(dǎo)致的既沒(méi)有提交又沒(méi)有回滾的事務(wù)所弄臟的數(shù)據(jù)塊。

             

            1.2.2 回滾

                   前滾一旦完畢,SMON進(jìn)程立即打開(kāi)數(shù)據(jù)庫(kù)。但是,這時(shí)的數(shù)據(jù)庫(kù)中還含有那些中間狀態(tài)的、既沒(méi)有提交又沒(méi)有回滾的臟塊,這種臟塊是不能存在于數(shù)據(jù)庫(kù)中的,因?yàn)樗鼈儾](méi)有被提交,必須被回滾。打開(kāi)數(shù)據(jù)庫(kù)以后,SMON進(jìn)程會(huì)在后臺(tái)進(jìn)行回滾。

             

                   有時(shí),數(shù)據(jù)庫(kù)打開(kāi)以后,SMON進(jìn)程還沒(méi)來(lái)得及回滾這些中間狀態(tài)的數(shù)據(jù)塊時(shí),就有用戶進(jìn)程發(fā)出讀取這些數(shù)據(jù)塊的請(qǐng)求。這時(shí),服務(wù)器進(jìn)程在將這些塊返回給用戶之前,由服務(wù)器進(jìn)程負(fù)責(zé)進(jìn)行回滾,回滾完畢后,將數(shù)據(jù)塊的內(nèi)容返回給用戶。

             

            總之,Crash Recovery時(shí),數(shù)據(jù)庫(kù)打開(kāi)會(huì)占用比正常關(guān)閉更長(zhǎng)的時(shí)間。

             

            1.2.3 必須先前滾,在回滾

                   回滾段實(shí)際上也是以回滾表空間的形式存在的,既然是表空間,那么肯定就有對(duì)應(yīng)的數(shù)據(jù)文件,同時(shí)在buffer cache 中就會(huì)存在映像塊,這一點(diǎn)和其他表空間的數(shù)據(jù)文件相同。

                  

                   當(dāng)發(fā)生DML操作時(shí),既要生成REDO(針對(duì)DML操作本身的REDO Entry)也要生成UNDO(用于回滾該DML操作,記錄在UNDO表空間中),但是既然UNDO信息也是使用回滾表空間來(lái)存放的,那么該DML操作對(duì)應(yīng)的UNDO信息(在BUFFER CACHE生成對(duì)應(yīng)中的UNDO BLOCK)就會(huì)首先生成其對(duì)應(yīng)的REDO信息(UNDO BLOCK's REDO Entry)并寫(xiě)入Log Buffer中。

             

                   這樣做的原因是因?yàn)锽uffer Cache中的有關(guān)UNDO表空間的塊也可能因?yàn)閿?shù)據(jù)庫(kù)故障而丟失,為了保障在下一次啟動(dòng)時(shí)能夠順利進(jìn)行回滾,首先就必須使用REDO日志來(lái)恢復(fù)UNDO段(實(shí)際上是先回復(fù)Buffer Cache中的臟數(shù)據(jù)塊,然后由Checkpoint寫(xiě)入U(xiǎn)NDO段中),在數(shù)據(jù)庫(kù)OPEN以后再使用UNDO信息來(lái)進(jìn)行回滾,達(dá)到一致性的目的。

                   生成完UNDO BLOCK's REDO Entry后才輪到該DML語(yǔ)句對(duì)應(yīng)的REDO Entry,最后再修改Buffer Cache中的Block,該Block同時(shí)變?yōu)榕K數(shù)據(jù)塊。

             

                   實(shí)際上,簡(jiǎn)單點(diǎn)說(shuō)REDO的作用就是記錄所有的數(shù)據(jù)庫(kù)更改,包括UNDO表空間在內(nèi)。

             

            1.2.4  Crash Recovery 再細(xì)分

            Crash Recovery 可以在細(xì)分成兩種:

            (1)    實(shí)例恢復(fù)(InstanceRecovery)

            (2)    崩潰恢復(fù)(CrashRecovery)

             

            InstanceRecovery與CrashRecovery是存在區(qū)別的:針對(duì)單實(shí)例(singleinstance)或者RAC中所有節(jié)點(diǎn)全部崩潰后的恢復(fù),我們稱(chēng)之為Crash Recovery。    而對(duì)于RAC中的某一個(gè)節(jié)點(diǎn)失敗,存活節(jié)點(diǎn)(surviving instance)試圖對(duì)失敗節(jié)點(diǎn)線程上redo做應(yīng)用的情況,我們稱(chēng)之為InstanceRecovery。

             

                   不管是Instance Recovery還是Crash Recovery,都由2個(gè)部分組成:cache recovery和transaction recovery。

             

                   根據(jù)官方文檔的介紹,Cache Recovery也叫Rolling Forward(前滾);而Transaction Recovery也叫Rolling Back(回滾)。

             

            更多內(nèi)容參考:

            還原真實(shí)的cache recovery

            http://blog.csdn.net/tianlesoftware/article/details/6547891

             

            Oracle 實(shí)例恢復(fù)時(shí) 前滾(roll forward) 后滾(rollback) 問(wèn)題

            http://blog.csdn.net/tianlesoftware/article/details/6286330

             

            1.3 Redo log 說(shuō)明

            REDO LOG 的數(shù)據(jù)是按照THREAD 來(lái)組織的,對(duì)于單實(shí)例系統(tǒng)來(lái)說(shuō),只有一個(gè)THREAD,對(duì)于RAC 系統(tǒng)來(lái)說(shuō),可能存在多個(gè)THREAD,每個(gè)數(shù)據(jù)庫(kù)實(shí)例擁有一組獨(dú)立的REDO LOG 文件,擁有獨(dú)立的LOG BUFFER,某個(gè)實(shí)例的變化會(huì)被獨(dú)立的記錄到一個(gè)THREAD 的REDO LOG 文件中。

             

            對(duì)于單實(shí)例的系統(tǒng),實(shí)例恢復(fù)(Instance Recovery)一般是在數(shù)據(jù)庫(kù)實(shí)例異常故障后數(shù)據(jù)庫(kù)重啟時(shí)進(jìn)行,當(dāng)數(shù)據(jù)庫(kù)執(zhí)行了SHUTDOWN ABORT 或者由于操作系統(tǒng)、主機(jī)等原因宕機(jī)重啟后,在ALTER DATABASE OPEN 的時(shí)候,就會(huì)自動(dòng)做實(shí)例恢復(fù)。

            在RAC 環(huán)境中,如果某個(gè)實(shí)例宕了,或者實(shí)例將會(huì)接管,替宕掉的實(shí)例做實(shí)例恢復(fù)。除非是所有的實(shí)例都宕了,這樣的話,第一個(gè)執(zhí)行ALTER DATABASE OPEN 的實(shí)例將會(huì)做實(shí)例恢復(fù)。這也是REDO LOG 是實(shí)例私有的組件,但是REDO LOG 文件必須存放在共享存儲(chǔ)上的原因。

             

            Oracle 數(shù)據(jù)庫(kù)的CACHE 機(jī)制是以性能為導(dǎo)向的,CACHE 機(jī)制應(yīng)該最大限度的提高數(shù)據(jù)庫(kù)的性能,因此CACHE 被寫(xiě)入數(shù)據(jù)文件總是盡可能的推遲。這種機(jī)制大大提高了數(shù)據(jù)庫(kù)的性能,但是當(dāng)實(shí)例出現(xiàn)故障時(shí),可能出現(xiàn)一些問(wèn)題。

             

            首先是在實(shí)例故障時(shí),可能某些事物對(duì)數(shù)據(jù)文件的修改并沒(méi)有完全寫(xiě)入磁盤(pán),可能磁盤(pán)文件中丟失了某些已經(jīng)提交事務(wù)對(duì)數(shù)據(jù)文件的修改信息。

            其次是可能某些還沒(méi)有提交的事務(wù)對(duì)數(shù)據(jù)文件的修改已經(jīng)被寫(xiě)入磁盤(pán)文件了。也有可能某個(gè)原子變更的部分?jǐn)?shù)據(jù)已經(jīng)被寫(xiě)入文件,而部分?jǐn)?shù)據(jù)還沒(méi)有被寫(xiě)入磁盤(pán)文件。

            實(shí)例恢復(fù)就是要通過(guò)ONLINE REDO LOG 文件中記錄的信息,自動(dòng)的完成上述數(shù)據(jù)的修復(fù)工作。這個(gè)過(guò)程是完全自動(dòng)的,不需要人工干預(yù)。

             

            1.3.1 如何確保已經(jīng)提交的事務(wù)不會(huì)丟失?

            解決這個(gè)問(wèn)題比較簡(jiǎn)單,Oracle 有一個(gè)機(jī)制,叫做Log-Force-at-Commit,就是說(shuō),在事務(wù)提交的時(shí)候,和這個(gè)事務(wù)相關(guān)的REDO LOG 數(shù)據(jù),包括COMMIT 記錄,都必須 從LOG BUFFER 中寫(xiě)入REDO LOG 文件,此時(shí)事務(wù)提交成功的信號(hào)才能發(fā)送給用戶進(jìn)程。通過(guò)這個(gè)機(jī)制,可以確保哪怕這個(gè)已經(jīng)提交的事務(wù)中的部分BUFFER CACHE 還沒(méi)有被寫(xiě)入數(shù)據(jù)文件,就發(fā)生了實(shí)例故障,在做實(shí)例恢復(fù)的時(shí)候,也可以通過(guò)REDO LOG 的信息,將不一致的數(shù)據(jù)前滾。

             

            1.3.2 如何在數(shù)據(jù)庫(kù)性能和實(shí)例恢復(fù)所需要的時(shí)間上做出平衡?

                   既確保數(shù)據(jù)庫(kù)性能不會(huì)下降,又保證實(shí)例恢復(fù)的快速,解決這個(gè)問(wèn)題,oracle是通過(guò)checkpoint 機(jī)制來(lái)實(shí)現(xiàn)的。

            Oracle 數(shù)據(jù)庫(kù)中,對(duì)BUFFER CAHCE 的修改操作是前臺(tái)進(jìn)程完成的,但是前臺(tái)進(jìn)程只負(fù)責(zé)將數(shù)據(jù)塊從數(shù)據(jù)文件中讀到BUFFERCACHE 中,不負(fù)責(zé)BUFFERCACHE 寫(xiě)入數(shù)據(jù)文件。BUFFERCACHE 寫(xiě)入數(shù)據(jù)文件的操作是由后臺(tái)進(jìn)程DBWR 來(lái)完成的。DBWR 可以根據(jù)系統(tǒng)的負(fù)載情況以及數(shù)據(jù)塊是否被其他進(jìn)程使用來(lái)將一部分?jǐn)?shù)據(jù)塊回寫(xiě)到數(shù)據(jù)文件中。這種機(jī)制下,某個(gè)數(shù)據(jù)塊被寫(xiě)回文件的時(shí)間可能具有一定的隨機(jī)性的,有些先修改的數(shù)據(jù)塊可能比較晚才被寫(xiě)入數(shù)據(jù)文件。

             

            而CHECKPOINT 機(jī)制就是對(duì)這個(gè)機(jī)制的一個(gè)有效的補(bǔ)充,CHECKPOINT 發(fā)生的時(shí)候,CKPT 進(jìn)程會(huì)要求DBWR 進(jìn)程將某個(gè)SCN 以前的所有被修改的塊都被寫(xiě)回?cái)?shù)據(jù)文件。這樣一旦這次CHECKPOINT 完成后,這個(gè)SCN 前的所有數(shù)據(jù)變更都已經(jīng)存盤(pán),如果之后發(fā)生了實(shí)例故障,那么做實(shí)例恢復(fù)的時(shí)候,只需要沖這次CHECKPOINT 已經(jīng)完成后的變化量開(kāi)始就行了,CHECKPOINT 之前的變化就不需要再去考慮了。

             

            1.3.3 有沒(méi)有可能數(shù)據(jù)文件中的變化已經(jīng)寫(xiě)盤(pán),但是REDO LOG 信息還在LOG BUFFER 中,沒(méi)有寫(xiě)入REDO LOG 呢?

                   這里引入一個(gè)名詞:Write-Ahead-Log,就是日志寫(xiě)入優(yōu)先。日志寫(xiě)入優(yōu)先包含兩方面的算法:

            第一個(gè)方面是,當(dāng)某個(gè)BUFFER CACHE 的修改的變化矢量還沒(méi)有寫(xiě)入REDO LOG 文件之前,這個(gè)修改后的BUFFER CACHE 的數(shù)據(jù)不允許被寫(xiě)入數(shù)據(jù)文件,這樣就確保了再數(shù)據(jù)文件中不可能包含未在REDO LOG 文件中記錄的變化;

            第二個(gè)方面是,當(dāng)對(duì)某個(gè)數(shù)據(jù)的UNDO 信息的變化矢量沒(méi)有被寫(xiě)入REDOLOG 之前,這個(gè)BUFFERCACHE的修改不能被寫(xiě)入數(shù)據(jù)文件。

             

            相關(guān)鏈接:

            RedoLogCheckpoint 和 SCN關(guān)系

            http://blog.csdn.net/tianlesoftware/article/details/5251916

             

            Oraclecheckpoint 說(shuō)明

            http://blog.csdn.net/tianlesoftware/article/details/6700085

             

             

            二.LOG BUFFER 和LGWR

             

            2.1 Redo Log 說(shuō)明

            REDO LOG是順序?qū)懙奈募看螌?xiě)入的數(shù)據(jù)量很小,TEMP文件雖然也就有部分順序讀寫(xiě)的特點(diǎn),但是TEMP每次讀寫(xiě)的數(shù)據(jù)量較大,和REDO 的特性不同。UNDO是典型的隨機(jī)讀寫(xiě)的文件,索引更是以單塊讀為主的操作。

             

            REDO LOG 的產(chǎn)生十分頻繁,幾乎每秒鐘都有幾百K 到幾M 的RED LOG 產(chǎn)生,甚至某些大型數(shù)據(jù)庫(kù)每秒鐘產(chǎn)生的REDO LOG 量達(dá)到了10M 以上。不過(guò)前臺(tái)進(jìn)程每次產(chǎn)生的REDO量卻不大,一般在幾百字節(jié)到幾K,而一般一個(gè)事務(wù)產(chǎn)生的REDO 量也不過(guò)幾K到幾十K。

             

            基于REDO 產(chǎn)生的這個(gè)特點(diǎn),如果每次REDO產(chǎn)生后就必須寫(xiě)入REDOLOG 文件,那么就會(huì)存在兩個(gè)問(wèn)題,一個(gè)是REDO LOG 文件寫(xiě)入的頻率過(guò)高,會(huì)導(dǎo)致REDO LOG文件的IO 存在問(wèn)題,第二個(gè)是如果由前臺(tái)進(jìn)程來(lái)完成REDO LOG 的寫(xiě)入,那么會(huì)導(dǎo)致大量并發(fā)的前臺(tái)進(jìn)程產(chǎn)生REDO LOG 文件的爭(zhēng)用。

             

            為了解決這兩個(gè)問(wèn)題,Oracle 在REDO LOG 機(jī)制中引入了LGWR 后臺(tái)進(jìn)程和LOGBUFFER。

            LOG BUFFER 是Oracle 用來(lái)緩存前臺(tái)進(jìn)程產(chǎn)生的REDO LOG 信息的,有了LOG BUFFER,前臺(tái)進(jìn)程就可以將產(chǎn)生的REDO LOG 信息寫(xiě)入LOG BUFFER,而不需要直接寫(xiě)入REDO LOG 文件,這樣就大大提高了REDO LOG 產(chǎn)生和保存的時(shí)間,從而提高數(shù)據(jù)庫(kù)在高并發(fā)情況下的性能。既然前臺(tái)進(jìn)程不將REDOLOG 信息寫(xiě)入REDO LOG 文件了,那么就必須要有一個(gè)后臺(tái)進(jìn)程來(lái)完成這個(gè)工作。這個(gè)后臺(tái)進(jìn)程就是LGWR,LGWR 進(jìn)程的主要工作就是將LOG BUFFER 中的數(shù)據(jù)批量寫(xiě)入到REDO LOG 文件中。對(duì)于Oracle 數(shù)據(jù)庫(kù)中,只要對(duì)數(shù)據(jù)庫(kù)的改變寫(xiě)入到REDO LOG 文件中了,那么就可以確保相關(guān)的事務(wù)不會(huì)丟失了。

             

            引入LOG BUFFER 后,提高了整個(gè)數(shù)據(jù)庫(kù)RDMBS 寫(xiě)日志的性能,但是如何確保一個(gè)已經(jīng)提交的事務(wù)確確實(shí)實(shí)的被保存在數(shù)據(jù)庫(kù)中,不會(huì)因?yàn)橹髷?shù)據(jù)庫(kù)發(fā)生故障而丟失呢?實(shí)際上在前面兩節(jié)中我們介紹的REDO LOG 的一些基本的算法確保了這一點(diǎn)。

            首先WRITE AHEAD LOG 協(xié)議確保了只要保存到REDO LOG 文件中的數(shù)據(jù)庫(kù)變化一定能夠被重演,不會(huì)丟失,也不會(huì)產(chǎn)生二義性。其次是在事務(wù)提交的時(shí)候,會(huì)產(chǎn)生一個(gè)COMMIT 的CV,這個(gè)CV 被寫(xiě)入LOG BUFFER 后,前臺(tái)進(jìn)程會(huì)發(fā)出一個(gè)信號(hào),要求LGWR 將和這個(gè)事務(wù)相關(guān)的REDO LOG 信息寫(xiě)入到REDO LOG 文件中,只有這個(gè)事務(wù)相關(guān)的REDO LOG 信息已經(jīng)確確實(shí)實(shí)被寫(xiě)入REDO LOG 文件的時(shí)候,前臺(tái)進(jìn)程才會(huì)向客戶端發(fā)出事務(wù)提交成功的消息,這樣一個(gè)事務(wù)才算是被提交完成了。在這個(gè)協(xié)議下,只要客戶端收到了提交完成的消息,那么可以確保,該事務(wù)已經(jīng)存盤(pán),不會(huì)丟失了。

             

            LGWR 會(huì)繞過(guò)操作系統(tǒng)的緩沖,直接寫(xiě)入數(shù)據(jù)文件中,以確保REDO LOG 的信息不會(huì)因?yàn)椴僮飨到y(tǒng)出現(xiàn)故障(比如宕機(jī))而丟失要求確保寫(xiě)入REDO LOG 文件的數(shù)據(jù)。

             

            實(shí)際上,雖然Oracle 數(shù)據(jù)庫(kù)使用了繞過(guò)緩沖直接寫(xiě)REDO LOG 文件的方法,以避免操作系統(tǒng)故障導(dǎo)致的數(shù)據(jù)丟失,不過(guò)我們還是無(wú)法確保這些數(shù)據(jù)已經(jīng)確確實(shí)實(shí)被寫(xiě)到了物理磁盤(pán)上。因?yàn)槲覀僐DBMS 使用的絕大多數(shù)存儲(chǔ)系統(tǒng)都是帶有寫(xiě)緩沖的,寫(xiě)緩沖可以有效的提高存儲(chǔ)系統(tǒng)寫(xiě)性能,不過(guò)也帶來(lái)了另外的一個(gè)問(wèn)題,就是說(shuō)一旦存儲(chǔ)出現(xiàn)故障,可能會(huì)導(dǎo)致REDO LOG 的信息丟失,甚至導(dǎo)致REDO LOG 出現(xiàn)嚴(yán)重?fù)p壞。存儲(chǔ)故障的概率較小,不過(guò)這種小概率事件一旦發(fā)生還是會(huì)導(dǎo)致一些數(shù)據(jù)庫(kù)事務(wù)的丟失,因此雖然Oracle 的內(nèi)部算法可以確保一旦事務(wù)提交成功,事務(wù)就確認(rèn)被保存完畢了,不過(guò)還是可能出現(xiàn)提交成功的事務(wù)丟失的現(xiàn)象。

             

            實(shí)際上,Oracle 在設(shè)計(jì)REDO LOG 文件的時(shí)候,已經(jīng)最大限度的考慮了REDO LOG 文件的安全性,REDO LOG 文件的BLOCK SIZE 和數(shù)據(jù)庫(kù)的BLOCK SIZE 是完全不同的,REDO LOG 文件的BLOCK SIZE 是和操作系統(tǒng)的IO BLOCK SZIE 完全相同的,這種設(shè)計(jì)確保了一個(gè)REDO LOG BLOCK 是在一次物理IO 中同時(shí)寫(xiě)入的,因此REDOLOG BLOCK 不會(huì)出現(xiàn)塊斷裂的現(xiàn)象。

             

            2.2 LOG BUFFER 說(shuō)明

             

            2.2.1 Log Buffer 說(shuō)明

            --官網(wǎng)的說(shuō)明:

            The redolog buffer is a circular buffer in the SGA that stores redo entriesdescribing changes made to the database. Redo entries contain theinformation necessary to reconstruct, or redo, changes made to the database byDML or DDL operations. Database recovery applies redo entries to data files toreconstruct lost changes.

            Oracle Databaseprocesses copy redo entriesfrom the user memory space to the redo log buffer in the SGA. The redo entriestake up continuous, sequential space in the buffer. The background process logwriter (LGWR) writes the redo log buffer to the active online redo loggroup on disk. Figure14-8 shows this redo buffer activity.

             

             

            LGWR writes redosequentially to disk while DBWn performs scattered writes of data blocksto disk. Scattered writes tend to be much slower than sequential writes.Because LGWR enable users to avoid waiting for DBWn to complete its slowwrites, the database delivers better performance.

             

            The LOG_BUFFER initializationparameter specifies the amount of memory that Oracle Database uses whenbuffering redo entries. Unlike other SGA components, the redo log buffer andfixed SGA buffer do not divide memory into granules.

             

            --MOS: [ID 147471.1]

            The redo logbuffer is a circular buffer in the SGA that holds information about changesmade to the database. This information is stored in redo entries. Redo entriescontain the information necessary to reconstruct, or redo changes made to thedatabase . Redo entries are used for database recovery, if necessary.

            Redo entries arecopied by Oracle server processes from the user's memory space to the redo logbuffer in the SGA. The redo entries take up continuous, sequential space in thebuffer. The background process LGWR writes the redo log buffer to the activeonline redo log file (or group of files) on disk.

            The initialization parameter LOG_BUFFER determines the size (in bytes) of the redolog buffer. In general, larger values reduce log file I/O, particularly iftransactions are long or numerous. The default setting is four times themaximum data block size for the host operating system prior to 8i and 512k or128k x cpu_count whichever is greater, from 8i onwards.

             

            -- MOS: [ID 147471.1]   Redolog Latches

                   Whena change to a data block needs to be done, it requires to create a redo recordin the redolog buffer executing the following steps:

            (1)    Ensure that no other processeshas generated a higher SCN

            (2)    Find for space available towrite the redo record. If there is no space available then the LGWR must writeto disk or issue a log switch

            (3)    Allocate the space needed inthe redo log buffer

            (4)    Copy the redo record to the logbuffer and link it to the appropriate structures for recovery purposes.

             

            The database has threeredo latches to handle this process:

            (1)Redo Copy latch

            The redocopy latch is acquired for the whole duration of the process describedabove. The init.ora LOG_SIMULTANEOUS_COPIES determines the number of redo copylatches. It is only released when a log switch is generated to release freespace and re-acquired once the log switch ends.

             

            (2)Redo  allocation latch

            The redoallocation latch is acquired to allocate memory space in the log buffer. BeforeOracle9.2, the redo allocation latch is unique and thus serializes the writingof entries to the log buffer cache of the SGA. In Oracle 9.2. EntrepriseEdition, the number of redo allocation latches is determined by init.oraLOG_PARALLELISM.   The redo allocation latch allocates space in the logbuffer cache for each transaction entry.  If transactions are small, or ifthere is only one CPU on the server, then the redo allocation latch also copiesthe transaction data into the log buffer cache. If a log switch is needed toget free space this latch is released as well with the redo copy latch.

             

            (3)Redo writing latch

            This uniquelatch prevent multiple processes posting the LGWR  process requesting logswitch simultaneously. A process that needs free space must acquire the latchbefore of deciding whether to post the LGWR to perform a write, execute a logswitch or just wait.

             

            -- MOS: [ID 147471.1]

            Instance ParametersRelated with the Redolog Latches 
             

            In Oracle7 andOracle 8.0, there are two parameters that modify the behavior of the latchallocation in the redolog buffer: LOG_SIMULTANEOUS_COPIES (This parametercontrols the number of redo copy latches when the system has morethan one CPU),  and LOG_SMALL_ENTRY_MAX_SIZE. When LOG_SIMULTANEOUS_COPIESis set to a non-zero value, and the size of the transaction entry is smallerthan the value of the LOG_SMALL_ENTRY_MAX_SIZE parameter then the copy of thetransaction entry into the log buffer cache is performed by the redoallocation latch.  If the size of the transaction entry exceedsLOG_SMALL_ENTRY_MAX_SIZE, then the transaction entry is copied into the logbuffer cache by the redo copy latch.

             

            In Oracle8i andOracle9.0, a redo copy latch is always required regardless of the redo size sothe check is no longer performed. The init.ora LOG_SIMULTANEOUS_COPIES becomesobsolete and the number of redo copy latches defaults to twice the number ofcpus. The parameter LOG_SMALL_ENTRY_MAX_SIZE is also obsolete. For furtherdetail on the change of this parameters in Oracle 8i seeNote:94271.1

             

            In Oracle9.2 andhigher, multiple redo allocation latches become possible with init.oraLOG_PARALLELISM. The log buffer is split in multiple LOG_PARALLELISM areas thateach have a size of init.ora LOG_BUFFER. The allocation job of each area isprotected by a specific redo allocation latch. The number of redo copy latchesis still determined by the number of cpus

             

            LOG BUFFER 是SGA中一塊循環(huán)使用的內(nèi)存區(qū)域,它一般很小.

            在Oracle 10g之前,LOG BUFFER參數(shù)的默認(rèn)設(shè)置為Max(512 KB,128 KB * CPU_COUNT),按照默認(rèn)設(shè)置,LOG_BUFFER消耗的內(nèi)存都不會(huì)太高,而由于LGWR對(duì)Log Buffer內(nèi)容的寫(xiě)出非常頻繁,所以很小的Log Buffer也可以工作得很好,根據(jù)經(jīng)驗(yàn),有很多對(duì)Log Buffer的指導(dǎo)性設(shè)置,比如經(jīng)常提到的3MB大小,但是在Oracle10g中,Redo Log Buffer默認(rèn)的已經(jīng)大大超過(guò)了原來(lái)的想象。

             

            這和Oracle 9i引入了Granule的概念有關(guān),在動(dòng)態(tài)SGA管理中,Granule是最小的內(nèi)存分配單元,其大小與SGA及操作系統(tǒng)平臺(tái)有關(guān)。

             

            在10g中ORACLE會(huì)自動(dòng)調(diào)整它的值,他遵循這樣一個(gè)原則,'Fixed SGA Size'+ 'Redo Buffers'是granule size 的整數(shù)倍(如果是一倍,那么他們的比值可能為0.999...如果是2倍,那么他們的比值可能是1.999...)。

            一般的granule value 為4194304 ,也就是4M, 而fixed size 一般為 1.2M,這個(gè)值不確定,也不精確,根據(jù)不同的平臺(tái)有所差異,而默認(rèn)的log_buffer+fixedsize 的大小為 granulesize 的整數(shù)倍,所以默認(rèn)的情況下你看見(jiàn)的log_buffer大小約為6.67m或者為2.7M。

             

            所以如果我們手動(dòng)的設(shè)置log_buffer的值,那么ORACLE會(huì)將它加上fixedsize 然后除以granule ,得到一個(gè)值,然后四舍五入,看最接近哪個(gè)整數(shù),然后就取最接近的那個(gè)值。

             

            SQL> select * from v$version whererownum <2; 

            BANNER

            ----------------------------------------------------------------

            Oracle Database 10g Enterprise EditionRelease 10.2.0.4.0 - Prod

             

            SQL> select * from v$sgainfo where namein ('Fixed SGA Size','Redo Buffers','Granule Size'); 

             

            NAME                                  BYTES RES

            -------------------------------- -------------

            Fixed SGA Size                      1270508 No

            Redo Buffers                        2920448 No

            Granule Size                        4194304 No

             

            SQL> select sum(bytes)/1024/1024 fromv$sgainfo where name in ('Fixed SGA Size','Redo Buffers'); 

             

            SUM(BYTES)/1024/1024

            --------------------

                      3.9968071

             

            --查看'FixedSGA Size' + 'Redo Buffers' 與 Granule Size的比值:

            SQL> select 3.9968071/4 from dual;

             

            3.9968071/4

            -----------

             .999201775

             

            這里驗(yàn)證了我們前面的說(shuō)法:'Fixed SGA Size' + 'Redo Buffers' 是Granule Size 整數(shù)倍。

             

            2.2.2 Log Buffer 中的Latch

            由于log buffer是一塊“共享”內(nèi)存,為了避免沖突,它是受到redo allocation latch保護(hù)的,每個(gè)服務(wù)進(jìn)程需要先獲取到該latch才能分配redobuffer。因此在高并發(fā)且數(shù)據(jù)修改頻繁的oltp系統(tǒng)中,我們通常可以觀察到redoallocation latch的等待。

             

                   為了減少redo allocation latch等待,在oracle 9.2中,引入了log buffer的并行機(jī)制。其基本原理就是,將log buffer劃分為多個(gè)小的buffer,這些小的buffer被成為Shared Strand。每一個(gè)strand受到一個(gè)單獨(dú)redo allocation latch的保護(hù)。多個(gè)shared strand的出現(xiàn),使原來(lái)序列化的redo buffer分配變成了并行的過(guò)程,從而減少了redo allocationlatch等待。

             

                   為了進(jìn)一步降低redo buffer沖突,在10g中引入了新的strand機(jī)制——Private strand。Private strand不是從log buffer中劃分的,而是在shared pool中分配的一塊內(nèi)存空間。

                  

            Private strand的引入為Oracle的Redo/Undo機(jī)制帶來(lái)很大的變化。每一個(gè)Private strand受到一個(gè)單獨(dú)的redo allocation latch保護(hù),每個(gè)Private strand作為“私有的”strand只會(huì)服務(wù)于一個(gè)活動(dòng)事務(wù)。獲取到了Private strand的用戶事務(wù)不是在PGA中而是在Private strand生成Redo,當(dāng)flush private strand或者commit時(shí),Privatestrand被批量寫(xiě)入log文件中。如果新事務(wù)申請(qǐng)不到Private strand的redo allocation latch,則會(huì)繼續(xù)遵循舊的redo buffer機(jī)制,申請(qǐng)寫(xiě)入shared strand中。事務(wù)是否使用Private strand,可以由x$ktcxb的字段ktcxbflg的新增的第13位鑒定。

             

                   對(duì)于使用Private strand的事務(wù),無(wú)需先申請(qǐng)Redo Copy Latch,也無(wú)需申請(qǐng)Shared Strand的redo allocation latch,而是flush或commit是批量寫(xiě)入磁盤(pán),因此減少了Redo Copy Latch和redo allocation latch申請(qǐng)/釋放次數(shù)、也減少了這些latch的等待,從而降低了CPU的負(fù)荷。

             

             

            2.2.3 Log Buffer 大小問(wèn)題

              一般默認(rèn)情況下的log_buffer的大小夠用了,查看Log_buffer是否需要調(diào)整,可以查看數(shù)據(jù)庫(kù)是否有大量的log buffer space等待事件出現(xiàn)。redo log 最開(kāi)始是在pga中的uga產(chǎn)生的(數(shù)據(jù)庫(kù)一般是專(zhuān)有模式),oracle會(huì)把它拷貝到SGA中的log_buffer中去,如果log_buffer過(guò)小,或者lgwr不能夠快速將redo 寫(xiě)入到log file中,那么就會(huì)產(chǎn)生log buffer space等待事件,遇到此類(lèi)問(wèn)題,可以增加 log_buffer大小,調(diào)整log file 到裸設(shè)備,I/0快的磁盤(pán)中。

             

            MOS有兩篇相關(guān)的文章:

            (1)Oracle Calculation of Log_Buffer Size in 10g [ID604351.1]

            A big difference can be seen between 10.2.0.3 and 10.2.0.4 when usingthe same system configuration (in terms of the application and its dbobjects and datafiles, ram size, number of CPUs etc). In 10.2.0.3 it was set byOracle to 14M and now in 10.2.0.4 to 15M. 

            --在10.2.0.3 中Log Buffer 默認(rèn)值是14M,在10.2.0.4中,默認(rèn)值是15M。

             

            The LOG_BUFFERsize will be set by default, by Oracle internal algorithm. 

             

            In 10G R2,Oracle combines fixed SGA area and redo buffer [log buffer] together. 

             

            (2)Tuning the Redolog Buffer Cache and Resolving RedoLatch Contention [ID 147471.1]

             

             

            相關(guān)內(nèi)容出處鏈接:

            http://www.dbtan.com/2009/12/set-redo-log-buffer-size.html

            http://www.dbtan.com/2009/12/redo-writes-triggering-condition.html

            http://book.51cto.com/art/201001/177245.htm

             

            Oracle 內(nèi)存 架構(gòu) 詳解

            http://blog.csdn.net/tianlesoftware/article/details/5594080

             

            Privatestrand flush not complete 說(shuō)明

            http://blog.csdn.net/tianlesoftware/article/details/6015400

             

             

            2.3 LOG BUFFER 和LGWR 的算法

            了解LOG BUFFER 和LGWR 的算法,有助于我們分析和解決相關(guān)的性能問(wèn)題,因此我們需要花一點(diǎn)時(shí)間來(lái)了解LOG BUFFER 相關(guān)的基本算法。用一句話來(lái)概括,LOG BUFFER是一個(gè)循環(huán)使用的順序型BUFFER。這句話里包含了兩個(gè)含義,一個(gè)是LOG BUFFER 是一個(gè)順序讀寫(xiě)的BUFFER,LOG BUFFER 數(shù)據(jù)的寫(xiě)入是順序的;第二個(gè)含義是LOG BUFFER是一個(gè)循環(huán)BUFFER,當(dāng)LOG BUFFER 寫(xiě)滿后,會(huì)回到頭上來(lái)繼續(xù)寫(xiě)入REDO LOG 信息。

             

            LOG BUFFER 數(shù)據(jù)的寫(xiě)入是由前臺(tái)進(jìn)程完成的,這個(gè)寫(xiě)入操作是并發(fā)的,每個(gè)前臺(tái)進(jìn)程在生成了REDOLOG 信息后,需要首先在LOGBUFFER 中分配空間,然后將REDOLOG 信息寫(xiě)入到LOGBUFFER 中去。在LOG BUFFER中分配空間是一個(gè)串行的操作,因此Oracle 在設(shè)計(jì)這方面的算法的時(shí)候,把LOG BUFFER 空間分配和將REDO LOG 數(shù)據(jù)拷貝到LOG BUFFER 中這兩個(gè)操作分離了,一旦分配了LOG BUFFER 空間,就可以釋放相關(guān)的閂鎖,其他前臺(tái)進(jìn)程就可以繼續(xù)分配空間了(這里所說(shuō)的前臺(tái)進(jìn)程只是一個(gè)泛指,是為了表述方便而已,讀者一定要注意,因?yàn)楹笈_(tái)進(jìn)程也會(huì)對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改,也需要產(chǎn)生REDO LOG 信息,后臺(tái)進(jìn)程的REDO 操作和前臺(tái)進(jìn)程是大體一致的)。

             

            前臺(tái)進(jìn)程寫(xiě)入REDO 信息會(huì)使LOG BUFFER的尾部指針不停的向前推進(jìn),而LGWR這個(gè)后臺(tái)進(jìn)程不聽(tīng)的從LOG BUFFER 的頭部指針處開(kāi)始查找還未寫(xiě)入REDO LOG 文件的LOG BUFFER 信息,并將這些信息寫(xiě)入REDO LOG 文件中,并且將BUFFER 頭部指針不停的向后推進(jìn),一旦LOG BUFFER 的頭部指針和尾部指針重合,那么就說(shuō)嘛了當(dāng)前的LOG BUFFER 是空的。

             

            而如果前臺(tái)進(jìn)程在LOG BUFFER 中分配空間會(huì)使LOG BUFFER 的尾部指針一直向前推進(jìn),一旦LOG BUFFER 的尾部指針追上了LOG BUFFER 的頭部指針,那么說(shuō)明目前LOG BUFFER 中無(wú)法分配新的空間給后臺(tái)進(jìn)程了,后臺(tái)進(jìn)程必須要等候LGWR將這些數(shù)據(jù)寫(xiě)入REDOLOG 文件,然后向前推進(jìn)了頭部指針,才可能再次獲得新的可用BUFFER 空間。這個(gè)時(shí)候,前臺(tái)進(jìn)程會(huì)等待LOG FILE SYNC 事件。

             

            為了讓LGWR 盡快將LOG BUFFER 中的數(shù)據(jù)寫(xiě)入REDO LOG 文件,以便于騰出更多的空閑空間,Oracle 數(shù)據(jù)庫(kù)設(shè)計(jì)了LGWR 寫(xiě)的觸發(fā)條件:

            1.     用戶提交 

            2.     有1/3重做日志緩沖區(qū)未被寫(xiě)入磁盤(pán) 

            3.      有大于1M的重做日志緩沖區(qū)未被寫(xiě)入磁盤(pán)

            4.     每隔3 秒鐘

             5. DBWR 需要寫(xiě)入的數(shù)據(jù)的SCN大于LGWR記錄的SCN,DBWR 觸發(fā)LGWR寫(xiě)入。 


            當(dāng)事務(wù)提交時(shí),會(huì)產(chǎn)生一個(gè)提交的REDO RECORD,這個(gè)RECORD 寫(xiě)入LOG BUFFER 后,前臺(tái)進(jìn)程會(huì)觸發(fā)LGWR 寫(xiě)操作,這個(gè)時(shí)候前臺(tái)進(jìn)程就會(huì)等待LOG FILE SYNC 等待,直到LGWR 將相關(guān)的數(shù)據(jù)寫(xiě)入REDOLOG 文件,這個(gè)等待就會(huì)結(jié)束,前臺(tái)進(jìn)程就會(huì)收到提交成功的消息。如果我們的系統(tǒng)中,每秒的事務(wù)數(shù)量較大,比如幾十個(gè)或者幾百個(gè),甚至大型OLTP 系統(tǒng)可能會(huì)達(dá)到每秒數(shù)千個(gè)事務(wù)。在這種系統(tǒng)中,LGWR由于事務(wù)提交而被激發(fā)的頻率很高,LOG BUFFER 的信息會(huì)被很快的寫(xiě)入REDO LOG 文件中。

             

            而對(duì)于某些系統(tǒng)來(lái)說(shuō),平均每個(gè)事務(wù)的大小很大,平均每個(gè)事務(wù)生成的REDO LOG 數(shù)據(jù)量也很大,比如1M 甚至更高,平均每秒鐘的事務(wù)數(shù)很少,比如1-2 個(gè)甚至小于一個(gè),那么這種系統(tǒng)中LGWR 由于事務(wù)提交而被激發(fā)的頻率很低,可能導(dǎo)致REDO LOG 信息在LOG BUFFER 中被大量積壓,oracle 設(shè)計(jì)的LOG BUFFER 中數(shù)據(jù)超過(guò)1M 的LGWR 激發(fā)條件就是為了解決這種情況而設(shè)計(jì)的,當(dāng)LOG BUFFER 中的積壓數(shù)據(jù)很多時(shí),雖然沒(méi)有事務(wù)提交,也會(huì)觸發(fā)LGWR 將BUFFER 中的數(shù)據(jù)寫(xiě)入REDO LOG 文件。

            除此之外,Oracle 還通過(guò)了_LOG_IO_SIZE 這個(gè)隱含參數(shù)來(lái)進(jìn)一步控制LGWR 寫(xiě)操作,當(dāng)LOGBUFFER 中的數(shù)據(jù)超過(guò)了這個(gè)隱含參數(shù)的規(guī)定的大小,也會(huì)觸發(fā)LGWR 被激發(fā)。這個(gè)參數(shù)的缺省值是LOGBUFFER 大小的1/3,這個(gè)參數(shù)單位是REDO LOG BLOCK。這個(gè)參數(shù)可以控制當(dāng)LOG BUFFER 中有多少個(gè)數(shù)據(jù)塊被占用時(shí),就要觸發(fā)LGWR 寫(xiě)操作,從而避免LOG BUFFER 被用盡。

             

            如果一個(gè)系統(tǒng)很空閑,很長(zhǎng)時(shí)間都沒(méi)有事務(wù)提交,LOG BUFFER 的使用也很少,就可能會(huì)導(dǎo)致LOG BUFFER 中的數(shù)據(jù)長(zhǎng)期沒(méi)有被寫(xiě)入REDO LOG 文件,帶來(lái)丟失數(shù)據(jù)的風(fēng)險(xiǎn),因此Oracle 還設(shè)計(jì)了一個(gè)LGWR 寫(xiě)的激發(fā)控件,設(shè)置了一個(gè)時(shí)間觸發(fā)器,每隔的尾部已經(jīng)追上了LOG BUFFER 的頭部,那么前臺(tái)進(jìn)程就要等待LGWR 進(jìn)程將頭部的數(shù)據(jù)寫(xiě)入REDOLOG 文件,然后釋放LOGBUFFER 空間。這個(gè)時(shí)候,沒(méi)有做提交操作的前臺(tái)進(jìn)程都會(huì)等待LOG FILE SYNC 事件。這種情況下,加大LOG BUFFER 就可能可以減少大部分的LOG FILE SYNC 等待了。

             

            加大LOG BUFFER 的大小,可能會(huì)帶來(lái)另外一個(gè)問(wèn)題,比如LOG BUFFER 從1M 增加到30M(關(guān)于LOG BUFFER 是否需要大于3M 的問(wèn)題,以前我們已經(jīng)多次討論,因此在這里不再討論了,大家只需要記住一點(diǎn)就可以了,LOG BUFFER 大于3M 浪費(fèi)空間,對(duì)性能影響不大的觀點(diǎn)是錯(cuò)誤的),那么_LOG_IO_SIZE 自動(dòng)會(huì)從300K 增加到10M,在一個(gè)平均每秒事務(wù)數(shù)較少,并且每個(gè)事務(wù)的REDO SIZE 較大的系統(tǒng)中,觸發(fā)LGWR 寫(xiě)操作的LOG BUFFER 數(shù)據(jù)量會(huì)達(dá)到1M。

            一般來(lái)說(shuō),在一個(gè)大型的OLTP 系統(tǒng)里,每次LGWR 寫(xiě)入REDO LOG 文件的大小在幾K 到幾十K 之間,平均LOG FILE SYNC 的時(shí)間在1-10 毫秒之間。如果平均每次寫(xiě)入的數(shù)據(jù)量過(guò)大,會(huì)導(dǎo)致LOG FILE SYNC 的等待時(shí)間變長(zhǎng)。因此在這種情況下,就可能需要設(shè)置_LOG_IO_SIZE 參數(shù),確保LOG FILE SYNC 等待不要過(guò)長(zhǎng)。

             

            如果每次寫(xiě)入REDO LOG 文件的數(shù)據(jù)量也不大,而LOG FILE SYNC 等待時(shí)間很吵,比如說(shuō)超過(guò)100 毫秒,那么我們就要分析一下REDOLOG 文件的IO 性能了,如果REDO LOG 文件IO 性能不佳,或者該文件所在的IO 熱點(diǎn)較大,也可能導(dǎo)致LOGFILE SYNC 等待時(shí)間偏大,這種情況,我們可以查看后臺(tái)進(jìn)程的LOG FILE PARALLEL WRITE 這個(gè)等待事件,這個(gè)等待事件一般的等待時(shí)間為幾個(gè)毫秒,如果這個(gè)等待事件的平均等待時(shí)間較長(zhǎng),那么說(shuō)明REDO LOG 文件的IO 性能不佳,需要將REDOLOG 文件放到IO 量較小,性能較快的磁盤(pán)上。

             

            在OLTP 系統(tǒng)上,REDO LOG 文件的寫(xiě)操作主要是小型的,比較頻繁,一般的寫(xiě)大小在幾K,而每秒鐘產(chǎn)生的寫(xiě)IO 次數(shù)會(huì)達(dá)到幾十次,數(shù)百次甚至上千次。因此REDO LOG文件適合存放于IOPS 較高的轉(zhuǎn)速較快的磁盤(pán)上,IOPS 僅能達(dá)到數(shù)百次的SATA 盤(pán)不適合存放REDO LOG 文件。另外由于REDO LOG 文件的寫(xiě)入是串行的,因此對(duì)于REDO LOG文件所做的底層條帶化處理,對(duì)于REDO LOG 寫(xiě)性能的提升是十分有限的。

             

             

            三.日志切換和REDO LOG 文件

            當(dāng)前臺(tái)進(jìn)程在LOG BUFFER 中分配空間的時(shí)候,實(shí)際上已經(jīng)在REDO LOG 文件中預(yù)先分配了空間,如果REDO LOG 文件已經(jīng)寫(xiě)滿,無(wú)法再分配空間給前臺(tái)進(jìn)程的時(shí)候,就需要做一次日志切換,這個(gè)時(shí)候前臺(tái)進(jìn)程會(huì)想LGWR 發(fā)出一個(gè)日志切換的請(qǐng)求,然后等待log file switch completion 等待事件。

             

            日志切換請(qǐng)求發(fā)出后,CKPT 進(jìn)程會(huì)進(jìn)行一次日志切換CHECKPOINT,而LGWR 開(kāi)始進(jìn)行日志切換工作。首先LGWR 進(jìn)程會(huì)通過(guò)控制文件中的雙向鏈表,查找到一個(gè)可用的REDO LOG 文件,作為新的CURRENT REDO LOG。 查找新的CURRENT REDO LOG 的算法是要求該日志是非ACTIVE 的,并且已經(jīng)完成了歸檔(如果是歸檔模式),oracle 會(huì)優(yōu)先使用unused 狀態(tài)的REDO LOG 組作為CURRENT REDO LOG。

             

            在做日志切換時(shí),首先要將LOG BUFFER 中還沒(méi)有寫(xiě)入REDO LOG 文件的REDO RECORD 寫(xiě)入當(dāng)前的REDO LOG 文件,然后將最后一個(gè)REDO RECORD 的SCN 作為本日志文件的HIGHSCN 記錄在REDO LOG 文件頭中。這些操作完成后,就可以關(guān)閉當(dāng)前日志了。

             

            完成了上一個(gè)步驟,就需要進(jìn)行第二次控制文件事務(wù),將剛剛關(guān)閉的REDO LOG 標(biāo)識(shí)為ACTIVE,將新的當(dāng)前REDO LOG標(biāo)識(shí)為CURRENT,如果數(shù)據(jù)庫(kù)處于歸檔模式,還要將老的日志組記錄到控制文件歸檔列表記錄中(在V$ARCHIVE 試圖中科看到),并且通知?dú)w檔進(jìn)程對(duì)該日志文件進(jìn)行歸檔。當(dāng)所有的歸檔進(jìn)程都處于忙狀態(tài)的時(shí)候,并且歸檔進(jìn)程總數(shù)沒(méi)有超過(guò)log_archive_max_processes 的情況下,LGWR 還會(huì)生成一個(gè)新的歸檔進(jìn)程來(lái)對(duì)老的日志文件進(jìn)行歸檔。

             

            這些操作完成后,LGWR 打開(kāi)新的日志組的所有成員,并在文件頭中記錄下初始化信息。

             

            這些完成后,LGWR 修改SGA 中的標(biāo)志位,允許生成新的REDO LOG 信息。老的日志組目前還被標(biāo)志位ACTIVE,當(dāng)DBWR 完成了CHECKPOINT 所要求的寫(xiě)批量操作后,該日志組的狀態(tài)會(huì)被標(biāo)識(shí)為inactive。

             

            從上述日志切換的步驟我們可以看出,日志切換還是有很多工作要做的,而且在日志切換開(kāi)始到結(jié)束之間,日志的生成是被完全禁止的,因此在這個(gè)期間,對(duì)數(shù)據(jù)庫(kù)的修改操作會(huì)被全部阻塞。這也是我們經(jīng)常提到的:“日志切換是一種較為昂貴的操作”。既然日志切換十分昂貴,對(duì)系統(tǒng)性能的影響較大,那么我們就應(yīng)該想辦法減少日志切換的數(shù)量,提高日志切換的速度。

             

            減少日志切換的數(shù)量我們可以從兩個(gè)方面去考慮,一方面是減少日志的產(chǎn)生量,一方面是加大日志文件的大小。

             

            對(duì)于減少日志產(chǎn)生量,常規(guī)的辦法不外乎使用NOLOGGING 操作,使用BULK 操作、使用DIRECTPATH WRITE 操作等。不過(guò)大家要注意在歸檔模式下合非歸檔模式下,這些NOLOGGING 操作的效果是不同的。

             

            有些DBA 擔(dān)心加大REDO LOG 文件后會(huì)增加數(shù)據(jù)丟失的機(jī)會(huì)。的確,REDO LOG 文件越大,一個(gè)REDO LOG 文件所包含的REDO RECORD 的數(shù)量就越多,一旦整個(gè)REDO LOG文件丟失或者損壞,可能丟失的數(shù)據(jù)量就會(huì)增加。

             

            實(shí)際上,整個(gè)REDO LOG 丟失的可能性極小,最主要的可能性是REDO LOG 文件被誤刪。如果存儲(chǔ)出現(xiàn)故障,導(dǎo)致了REDO LOG 文件損壞,那么受影響的肯定是所有的REDO LOG 文件,而不是某一個(gè)REDO LOG 文件,無(wú)論REDO LOG 信息是存在一個(gè)REDO LOG 文件中還是存在2 個(gè)REDO LOG 文件中,其結(jié)果是完全一樣的。

             

            剩下一種情況就是最常見(jiàn)的情況了,就是服務(wù)器突然宕機(jī),我們可以來(lái)分析一下服務(wù)器宕機(jī)這種情況,REDO LOG 文件的大小不同可能造成的數(shù)據(jù)丟失是否會(huì)不同。

            首先我們要了解一下服務(wù)器宕機(jī)時(shí)可能丟失的數(shù)據(jù)可能是哪些,如果是已經(jīng)提交的數(shù)據(jù),CHECKPOINT已經(jīng)推進(jìn)到的部分,是已經(jīng)被寫(xiě)入數(shù)據(jù)文件了,這部分?jǐn)?shù)據(jù)是無(wú)論如何都不會(huì)丟失的,REDO LOG 是用來(lái)恢復(fù)最后一次CHECKPOINT 到宕機(jī)前被寫(xiě)入REDO LOG 文件的那部分?jǐn)?shù)據(jù)。

             

            由于REDO LOG 文件的寫(xiě)入是順序的,因此無(wú)論這部分?jǐn)?shù)據(jù)被寫(xiě)入到一個(gè)文件還是多個(gè)文件,并不影響這部分?jǐn)?shù)據(jù)的恢復(fù)。因此我們可以看出,REDO LOG 文件大小和服務(wù)器宕機(jī)丟失數(shù)據(jù)的數(shù)量是無(wú)關(guān)的。

             

            通過(guò)前面的分析我們應(yīng)該已經(jīng)了解到,系統(tǒng)故障時(shí)只有當(dāng)整個(gè)REDO LOG 文件損壞時(shí),REDO LOG 文件的大小才可能與丟失的數(shù)據(jù)量有關(guān)。在絕大多數(shù)情況下,加大REDO LOG 文件的大小并不會(huì)增加數(shù)據(jù)丟失的機(jī)會(huì)。因此我們?cè)诳紤]REDO LOG 文件大小的時(shí)候,基本上可以忽略這個(gè)數(shù)據(jù)丟失的多少的問(wèn)題。

             

            不過(guò)在某些情況下,我們?cè)谛枰哟驲EDO LOG 文件大小的時(shí)候,要適當(dāng)?shù)目紤],一是存在DATA GUARD 的情況下,為了減少FAILOVER 時(shí)的數(shù)據(jù)丟失量,我們不宜將REDO LOG 文件設(shè)置的過(guò)大。另外在存在CDC 或者流復(fù)制下游捕獲的環(huán)境下,也需要考慮REDO LOG 文件大小和捕獲延時(shí)的關(guān)系問(wèn)題。

            很多DBA 都受過(guò)教育,就是REDO LOG 切換的時(shí)間應(yīng)該盡可能的不低于10-20 分鐘,如果日志切換間隔低于這個(gè)值,就要考慮加大REDO LOG 文件的大小。事實(shí)上,沒(méi)有任何鐵律,只要日志切換并沒(méi)有對(duì)系統(tǒng)的性能和安全產(chǎn)生嚴(yán)重的影響.

             

             

            Redo Log 和Checkpointnot complete

            http://blog.csdn.net/tianlesoftware/article/details/4908066

             

            Oracle 不同故障的恢復(fù)方案

            http://blog.csdn.net/tianlesoftware/archive/2010/12/30/6106178.aspx

             

            Currentonline Redo 和 Undo 損壞的處理方法

            http://blog.csdn.net/tianlesoftware/article/details/6261475

             

             

            posted on 2013-01-08 19:20 周強(qiáng) 閱讀(4899) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): c/c++

            91精品国产91久久| 久久精品无码一区二区无码| 9191精品国产免费久久| 国产精品欧美亚洲韩国日本久久| 国产精品久久亚洲不卡动漫| 色偷偷888欧美精品久久久| 99热都是精品久久久久久| 久久亚洲2019中文字幕| 亚洲综合精品香蕉久久网| AV色综合久久天堂AV色综合在| 99久久婷婷国产一区二区| 国产精品久久久香蕉| 国产精品久久成人影院| 日韩欧美亚洲国产精品字幕久久久| 2020久久精品亚洲热综合一本| 精品久久一区二区三区| 中文字幕精品久久| 99久久国产免费福利| 午夜天堂av天堂久久久| 久久精品亚洲精品国产欧美| 国产精品久久久久影视不卡| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 人妻丰满?V无码久久不卡| 久久久久亚洲AV片无码下载蜜桃| 久久人人爽人人精品视频| 久久精品国产福利国产秒| 午夜精品久久久久久久| 无码8090精品久久一区| 国产叼嘿久久精品久久| 99国产精品久久| 99久久人妻无码精品系列蜜桃 | 日韩av无码久久精品免费| 久久久久亚洲国产| 亚洲AV伊人久久青青草原| 久久久久亚洲AV无码专区桃色| 国产精品99久久99久久久| 少妇高潮惨叫久久久久久| 久久久久亚洲Av无码专| 国产Av激情久久无码天堂| 久久永久免费人妻精品下载| 乱亲女H秽乱长久久久|