REDO LOG是Oracle為確保已經提交的事務不會丟失而建立的一個機制。實際上REDO LOG的存在是為兩種場景准備的,一種我們稱之為實例恢復(INSTANCE RECOVERY),一種我們稱之為介質恢復(MEDIA RECOVERY)。實例恢復的目的是在數據庫發生故障時,確保BUFFER CACHE中的數據不會丟失,不會造成數據庫的不一致。介質恢復的目的是當數據文件發生故障時,能夠恢復數據。雖然這兩種恢復使用的機制類似的,但是這兩種恢復也有著十分本質的不同,這一點也是很多DBA經常會混淆的。
REDO LOG的數據是按照THREAD來組織的,對於單實例系統來說,只有一個THREAD,對於RAC系統來說,可能存在多個THREAD,每個數據庫實例擁有一組獨立的REDO LOG文件,擁有獨立的LOG BUFFER,某個實例的變化會被獨立的記錄到一個THREAD的REDO LOG文件中。
對於介質恢復和實例恢復來說,第一個步驟都是通過REDO LOG的信息進行前滾,在做前滾的時候,通過REDO LOG文件裡記錄的數據庫變化矢量(稍後我們會詳細的介紹數據庫變化矢量CV),根據SCN的比對,提交到相關的數據文件上,從而使數據文件的狀態向前滾動。大家要注意的是,UNDO表空間的變化也被記錄到REDO LOG裡了,因此UNDO表空間相關的數據文件也會被前滾。當前滾到最後一個可用的REDO LOG或者歸檔日志的時候,所有的數據庫恢復層面的工作就全部完成了。這個時候,數據庫包含了所有的被記錄的變化,這些變化中有些是已經提交,有些是尚未提交的。在最新狀態的UNDO表空間中,我們也可以看到一些尚未提交的事務。
因此數據庫下一步需要做的事情是事務層面的處理,回滾那些尚未提交的事務,以確保數據庫的一致性。
對於單實例的系統,實例恢復一般是在數據庫實例異常故障後數據庫重啟時進行,當數據庫執行了SHUTDOWN ABORT或者由於操作系統、主機等原因宕機重啟後,在ALTER DATABASE OPEN的時候,就會自動做實例恢復。而在RAC環境中,如果某個實例宕了,或者的實例將會接管,替宕掉的實例做實例恢復。除非是所有的實例都宕了,這樣的話,第一個執行ALTER DATABASE OPEN的實例將會做實例恢復。這也是REDO LOG是實例私有的組件,但是REDO LOG文件必須存放在共享存儲上的原因。
Oracle數據庫的CACHE機制是以性能為導向的,CACHE機制應該最大限度的提高數據庫的性能,因此CACHE被寫入數據文件總是盡可能的推遲。這種機制大大提高了數據庫的性能,但是當實例出現故障時,可能出現一些問題。
首先是在實例故障時,可能某些事物對數據文件的修改並沒有完全寫入磁盤,可能磁盤文件中丟失了某些已經提交事務對數據文件的修改信息。其次是可能某些還沒有提交的事務對數據文件的修改已經被寫入磁盤文件了。也有可能某個原子變更的部分數據已經被寫入文件,而部分數據還沒有被寫入磁盤文件。實例恢復就是要通過ONLINE REDO LOG文件中記錄的信息,自動的完成上述數據的修復工作。這個過程是完全自動的,不需要人工干預。
在這個機制裡,有兩個問題需要解決,第一個是如何確保已經提交的事務不會丟失,第二個是如何在數據庫性能和實例恢復所需要的時間上做出平衡,既確保數據庫性能不會下降,又保證實例恢復的快速。
解決第一個問題比較簡單,Oracle有一個機制,叫做Log-Force-at-Commit,就是說,在事務提交的時候,和這個事務相關的REDO LOG數據,包括COMMIT記錄,都必須從LOG BUFFER中寫入REDO LOG文件,此時事務提交成功的信號才能發送給用戶進程。通過這個機制,可以確保哪怕這個已經提交的事務中的部分BUFFER CACHE還沒有被寫入數據文件,就發生了實例故障,在做實例恢復的時候,也可以通過REDO LOG的信息,將不一致的數據前滾。
解決第二個問題,oracle是通過checkpoint機制來實現的。Oracle數據庫中,對BUFFER CAHCE的修改操作是前台進程完成的,但是前台進程只負責將數據塊從數據文件中讀到BUFFER CACHE中,不負責BUFFER CACHE寫入數據文件。BUFFER CACHE寫入數據文件的操作是由後台進程DBWR來完成的。DBWR可以根據系統的負載情況以及數據塊是否被其他進程使用來將一部分數據塊回寫到數據文件中。這種機制下,某個數據塊被寫回文件的時間可能具有一定的隨機性的,有些先修改的數據塊可能比較晚才被寫入數據文件。而CHECKPOINT機制就是對這個機制的一個有效的補充,CHECKPOINT發生的時候,CKPT進程會要求DBWR進程將某個SCN以前的所有被修改的塊都被寫回數據文件。這樣一旦這次CHECKPOINT完成後,這個SCN前的所有數據變更都已經存盤,如果之後發生了實例故障,那麼做實例恢復的時候,只需要沖這次CHECKPOINT已經完成後的變化量開始就行了,CHECKPOINT之前的變化就不需要再去考慮了。
到目前為止,我們了解了實例恢復機制的一些基本的原理,我們也可以大體上理解REDO LOG的工作機制了。不過我想我們還需要再更加深入一些。了解一些更為深入的內幕。實際上通過上面老白的介紹,大家也許已經覺得對實例恢復了解的很透徹了,而實際上,有很多問題我們還沒有解決。有些愛動腦筋的讀者可能要問了,有沒有可能數據文件中的變化已經寫盤,但是REDO LOG信息還在LOG BUFFER中,沒有寫入REDO LOG呢,這種情況如何恢復呢?
這裡我們又要引入一個名詞:Write-Ahead-Log,就是日志寫入優先。日志寫入優先包含兩方面的算法,第一個方面是,當某個BUFFER CACHE的修改的變化矢量還沒有寫入REDO LOG文件之前,這個修改後的BUFFER CACHE的數據不允許被寫入數據文件,這樣就確保了再數據文件中不可能包含未在REDO LOG文件中記錄的變化;第二個方面是,當對某個數據的UNDO信息的變化矢量沒有被寫入REDO LOG之前,這個BUFFER CACHE的修改不能被寫入數據文件。
介質恢復和實例恢復的機制是類似的,所不同的是,介質恢復是當存儲的數據文件出現故障的時候進行的,介質恢復無法自動進行,必須手工執行recover Database或者recover datafile命令來實施。一般來說,介質恢復是從一個恢復的數據文件為起點進行恢復,因此在做介質恢復的時候,需要使用歸檔日志。
轉載來自白鳝的洞穴
簡要摘要:
redo log的作用:
1.作為介質恢復數據庫的重要文件
2.作為實例恢復數據庫,保持數據庫一致性起重要作用
做實例恢復的時候,一致性的重要關鍵是redo log file,oracle保證所有的commit成功信息是首先寫入redo logfile,再更改datafile。而更改dataifle的時候,是先寫buffer cache
對於buffer cache寫入數據文件的dbwr進程,寫入一半掉電導致的不一致,oracle使用的是chkp進程進行定時唰寫datafile。(checkpoint會定時刷新大於指定SCN以前的事務強制回寫datafile)。
但是redo log的寫入,是先寫入redo log buffer,如果redo log buffer沒有寫入redo logfile怎麼辦?
1.當某個BUFFER CACHE的修改的變化矢量還沒有寫入REDO LOG文件之前,這個修改後的BUFFER CACHE的數據不允許被寫入數據文件。
2.當對某個數據的UNDO信息的變化矢量沒有被寫入REDO LOG之前,這個BUFFER CACHE的修改不能被寫入數據文件。