熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

Oracle恢復內部原理

2022-06-13   來源: Oracle 

    簡介

  Oracle數據庫提供了下列兩類失敗模式下的數據庫恢復

  實例失敗丟失了Oracle數據緩存中的數據或者內存中的數據

  介質失敗丟失了數據庫文件

  上面兩種模式的任一種失敗情景在恢復的時候想要保證數據庫一致性都有一些前提條件必須滿足

  雖然恢復的過程有一些共同點但前提條件的差異使得恢復的執行也有很大差異

  實例恢復恢復Oracle數據緩存中丟失的數據

  介質恢復恢復數據庫文件丟失的數據

    實例恢復和介質恢復的共同的機制

  實例恢復和介質恢復都依賴重做日志重做日志由一些重做日志線程組成單實例環境中重做日志只有一個重做線程多實例環境中每個實例都有一個重做線程

  一個重做日志線程指的的是一組存放在操作系統上的文件文件裡記錄了該實例對數據庫的所有變更已提交的變更和未提交的變更(後者指還存在Oracle數據緩存區中的數據塊變更)因為實例也修改了回滾段中的塊所以回滾段的變更也記錄在重做日志線程中

  實例恢復和介質恢復的第一步都是前滾前滾屬於數據庫恢復層面的在前滾的過程中重做日志中記錄的數據變更被重新應用到數據文件中因為回滾段的變更也記錄在重做日志中所以前滾過程還會重新構建回滾段塊當前滾結束時重做日志中記錄的所有變更都應用到數據文件上了此刻數據塊不僅包含了已經提交的數據也包含了一些未提交的數據

  實例恢復和介質恢復的第二步就是回滾回滾屬於數據庫事務層的任務回滾過程中回滾段中記錄的由前滾導致的未提交的事務所做的修改將被撤銷

    實例失敗和恢復崩潰失敗和恢復

  實例失敗指當實例突然終止時(如因為shutdown abort或主機掉電)實例數據緩存中的內容就都丟失了

  崩潰失敗指數據庫的所有實例都同時失敗單實例環境中實例失敗等同於崩潰失敗崩潰恢復指的是將所有實例都恢復到崩潰前的一致狀態這一切都是在命令alter database open 之後自動進行的用戶無法干預

  實例失敗會損害數據庫的一致性因為它導致該實例的髒數據丟失所謂髒數據就是指實例數據緩存中的數據塊內容比數據文件上的要新當實例崩潰時還沒有來得及將髒數據寫入到數據文件中之所以導致存在這個髒數據丟失問題是因為Oracle的緩存管理采用的是有利於事務處理性能的算法而不是有利於防止實例崩潰的如下這些有利於性能調優的緩存管理算法使得實例恢復過程有點復雜

  LRU(最近最少使用)緩存替換算法

  提交時不強制將髒數據刷新到數據文件中

  上面的算法導致實例失敗時對數據庫完整性的損害體現在如下幾點

  A在實例崩潰時數據文件中可能包含一個原子事務修改的所有塊中的部分塊而不是全部

  B在實例崩潰時數據文件中可能包含一些未提交事務修改的塊

  C在實例崩潰時一些已提交事務修改的塊可能還沒有刷新到數據文件中數據文件中包含的是該事務修改之前的數據塊

  在實例恢復過程中數據庫恢復層修復了上面的損害點A和C然後後續的數據庫事務層修復了損害點B

  除了那些用來修復數據庫完整性損害的前提條件外實例恢復還需要滿足一些前提條件

  實例恢復必須在聯機的數據文件上進行恢復

  實例恢復必須使用聯機重做日志文件不能要求使用歸檔重做日志文件雖然實例恢復也可以通過使用歸檔重做日志文件進行恢復(數據庫運行在非歸檔模式除外)但那種恢復過程在要求用戶先還原歸檔日志文件的的時候是不能自動進行的

  實例恢復過程的調用是自動的隱含的在下次數據庫啟動的時候被調用

  實例恢復過程中偵測修復的文件或修復過程本身都是自動進行的無需人工干預

  實例恢復中前滾時間的長短是由Oracle數據庫內部機制(checkpoint)和用戶配置的參數(如日志文件的大小和數量checkpoint的頻率並行恢復的參數等)決定的

  綜上所述Oracle的內存管理策略適合於性能調優而不是降低實例崩潰的影響本文描述了Oracle為解決采用這種LRU和提交不刷新數據塊的算法帶來的問題所用到的一些內部機制這些機制保證了實例恢復的前提條件得到滿足同時又兼顧了數據庫性能這些機制如下

  提交前先刷新日志塊

  這個機制修復損害C保證了在事務提交的時候所有跟該事務有關的重做日志記錄包括提交記錄都已經寫入到重做日志文件中

  檢查點機制

  界定了實例恢復時必須應用的重做日志的量這一點跟聯機日志切換結合起來使用確保實例恢復的時候只需要聯機重做日志和當前聯機數據文件

  聯機重做日志切換機制

  跟檢查點機制結合起來使用確保實例恢復的時候只需要聯機重做日志和當前聯機數據文件它保證當前的檢查點總是超前即將被重用的聯機重做日志文件

  寫日志優先

  這個機制修復損害AB因為a)在實例崩潰時刻數據文件上的所有變更都在重做日志中找到記錄b)所有數據塊在寫到數據文件之前都先寫入跟回滾段和數據塊的重做記錄

  寫重做日志記錄是原子的

  這個機制可以修復損害AB(注每筆重做日志記錄都是由三個部分組成重做日志記錄頭回滾段改變向量數據庫改變向量這三部分在寫入重做日志時是原子的不可分割的!)

  線程打開標志位

  用於數據庫啟動時判斷是否需要崩潰恢復

    介質失敗和恢復

  實例失敗影響邏輯上的數據庫完整性因為實例失敗的時候數據文件是可以恢復到一致狀態的實例恢復以當前數據文件為起點用聯機重做日志進行恢復

  介質失敗則不同影響的是物理上的數據庫完整性或可用性因為數據文件已經損壞介質恢復要先還原該數據文件的備份作為介質恢復的起點用歸檔重做日志和聯機重做日志做前滾操作直至數據文件備份後實例崩潰前最近的一個一致狀態或者數據文件備份後實例崩潰前的任意一個一致狀態介質恢復操作必須由下面命令來執行RECOVER DATABASE RECOVER TABLESPACE RECOVER DATAFILE

  根據失敗場景分析介質失敗對數據庫完整性的破壞可能跟實例失敗一樣如當一個塊被讀入到數據緩沖區中修改後正要被DBWR進程將更新後的數據塊寫回到數據文件中時發生I/O故障也可能導致前面提到的ABC三點損害此外介質失敗時不僅僅是當前髒數據永久丟失了而且該數據文件上自上次備份後的所有更新的都丟失了

  在介質恢復之前必須先還原被損壞的數據文件然後在這些數據文件上應用相關的歸檔日志和聯機重做日志前滾到介質失敗前的一致狀態

  介質恢復和實例恢復上面提到ABC三種損害有一些共同的前提條件然而介質恢復和實例恢復的前提條件還是有如下五點不同

  介質恢復前必須先還原受損壞的數據文件

  介質恢復除了要求聯機重做日志外還要有歸檔重做日志

  介質恢復必須顯示調用需要人工干預

  介質失敗不能自動被偵測到只有在某個數據文件或數據庫備份被還原的時候才能自動偵測到需要介質恢復

  介質恢復所用的前滾時間長短是由用戶備份策略決定的(如備份的頻率並行恢復參數等)而不是有Oracle內部機制決定

    基礎數據結構

    Controlfile

  控制文件包含了數據庫中所有其他文件的狀態信息

  控制文件包含了如下幾類數據

  A數據庫信息記錄(一條)

  B數據文件記錄(每個數據文件一條)

  C線程記錄(每個線程一條每個實例一個線程)

  D日志文件記錄(每個日志文件一條)

  E文件名記錄(每個數據文件或者日志文件成員一條)

  F日志歷史記錄(每個已經完成的日志文件一條)

  控制文件的被後面文檔引用到的字段如下後面是引用該字段的章節

    數據庫信息記錄(控制文件)

  所含字段

  A.resetlogs timestamp:

  B.resetlogs scn:

  C.enabled thread bitvec:

  D.force archiving scn:

  E.database checkpoint thread(thread record index) :

    數據文件記錄(控制文件)

  A.thread checkpoint structure:

  B.threadopen flag:

  C.current log (logfile record index)

  D.head and tail (logfile record indices) of list of logfiles in thread:

    日志文件記錄(控制文件)

  A.log sequence number:

  B.thread number:

  C.next and previous (logfile record indices) of list of logfiles in thread:

  D.count of files in group:

  E.low SCN:

  F.next SCN:

  G.head and tail (filename record indices) of list of filenames in group:

  H.being cleared flag:

  I.archiving not needed flag:

    文件名記錄(控制文件)

  A.filename

  B.filetype

  C.next and previous (filename record indices) of list of filenames in group:

    日志文件歷史記錄(控制文件)

  A.thread number:

  B.log sequence number:

  C.low SCN:

  D.low SCN timestamp:

  E.next SCN:

    數據文件頭

  數據文件頭部分的被後面文檔引用的字段如下後面跟的是引用該字段的章節:

  A.datafile checkpoint structure:

  B.backup checkpoint structure:

  C.checkpoint counter:

  D.esetlogs timestamp:

  E.resetlogs SCN:

  F.creation SCN:

  G.onlinefuzzy bit:

  H.hotbackupfuzzy bit:

  I.mediarecoveryfuzzy bit:

    日志文件頭

  日志文件頭部分的被後面文檔引用的字段如下後面跟的是引用該字段的章節:

  A.thread number:

  B.sequence number:

  C.low SCN:

  D.next SCN:

  E.endofthread flag:

  F.resetlogs timestamp:

  G.resetlogs SCN:

    改變向量(Change Vector)

  改變向量表示對數據塊的一次變更改變向量頭部記錄了發生變更的數據塊的DBA地址該塊的版本號序列值和操作代碼頭部以後的內容跟具體的變更操作有關數據塊版本號和序列值是在創建改變向量時從數據塊的頭部復制過來的當塊被更新後版本號值就比原來的值大一點而序列號則被設為此後數據塊每變更一次序列值就增長

    重做記錄

  一個重做記錄是由一組改變向量組成代表一個數據庫變更如一個事物的重做記錄由三部分組成首先是事務表(回滾段段首)的改變向量再次是回滾塊的改變向量最後是數據塊的改變向量一個事物可以產生多個重做記錄組成一個重做記錄是數據庫恢復的最小單位一個重做記錄由多個改變向量組成的機制允許多個數據塊被修改並且這些修改要麼都發生要麼就都沒發生即使發生突然的失敗這種原子性是由數據庫緩沖層的一個基礎Job來保證的Oracle恢復保證重做記錄是不可分割的即使在數據庫失敗的時候

    System Change Number (SCN)

  SCN描述了數據庫的一次事物提交版本一次查詢也是查詢數據庫的某個SCN產生時刻時的內容SCN會被分配和保存在事務的重做記錄的頭部SCN也會保存在控制文件和數據文件中SCN是由位長的數字組成

    重做日志

  所有數據塊的變更發生時都是先構建一個重做記錄然後把這個重做記錄保存到重做日志中最後在數據塊中應用該變更恢復的過程就是在老的數據塊上應用重做日志是該數據塊變成當前的數據塊這個過程在當前版本數據丟失的情況下是必須的

  當一個重做日志文件寫滿了時就會發生日志切換每個日志是由一個線程號標識序列號(一個線程以內再分)和該日志跨越的SCN范圍這些信息保存在日志文件頭中

  重做日志文件中的重做記錄是根據SCN排序的此外重做記錄中包含的具體數據塊的改變向量也是按SCN遞增順序發生的即使是跨多個線程(這種情況發生在多個實例環境中)只有某些重做記錄頭部包含有SCN信息但是所有的記錄都是在某個SCN被分配後才發生的日志文件的頭部包含了最小的SCN和下一個SCN最小的SCN是這個日志文件中第一個重做記錄對應的SCN下一個SCN是當前日志序列遞增後的下一個日志文件的的最小SCN當前在使用的重做日志的下一個SCN都是無限大因為還沒有日志文件的序列號比當前日志的序列要大

    重做線程

  每個實例產生的重做日志被稱為一個重做日志線程一個日志線程由聯機重做日志和歸檔重做日志(前提是數據庫運行在歸檔模式下)聯機重做日志是由兩個或更多個日志組組成每個日志組由一個或更多重復的日志成員組成通常說一個日志組重做日志聯機日志或簡稱日志都是指一個日志組的成員集合(可能是一個或者多個)一個重做日志只包含該日志所屬的線程記錄的日志各個線程在寫日志時分配日志文件的序列號是彼此獨立的各個線程的日志組之間的日志切換也是獨立進行的

  每個日志文件組在控制文件中都有一筆記錄描述它的信息每筆記錄通過日志號碼查找注意日志號跟日志組的號碼是一致的而且是全局唯一的(多實例環境中)每個重做線程的日志文件組列表記錄都在每個重做線程記錄的後面(類似於一種HeadDetail結構)各個日志文件組的記錄中都分別有一個向前和向後的字段記錄上一個日志文件組和下一個日志文件組(通過日志文件組號來記錄)日志文件組的成員信息在日志文件組的記錄中描述

    Redo Byte Address (RBA)

  RBA指定了重做日志的位置長度為字節由三部分組成日志序號塊號以及塊中的字節序號

    檢查點結構

  檢查點結構定義了數據庫重做日志的一個點檢查點結構信息保存數據文件頭部和控制文件中每個重做線程的記錄中這些檢查點結構用於恢復時告訴數據庫從哪個重做日志的哪一筆重做記錄開始恢復

  檢查點結構的關鍵字段是檢查點SCN和當前激活的線程標志

  檢查點SCN能有效的定位每個激活中重做日志的任一位置(激活的定義見對於每個重做線程檢查點SCN就是發生一次提交時的時間點以及對應重做日志的位置根據重做日志文件頭部的重做記錄可以發現第一筆重做記錄產生時分配的SCN是檢查點SCN或更高一點

  當前激活的線程標志標記了這個檢查點SCN被分配時哪個重做線程處於激活狀態注意每個線程在激活時都有一個狀態位被設置不管它是打開還是關閉狀態每個激活的線程都有一個重做日志重做日志包含該檢查點SCN這點證明了該重做日志存在(聯機或者已經歸檔)

  檢查點結構還還保存了這個檢查點SCN被分配時的時間戳這個時間戳只是輸出一些信息便於用戶查找日志

  此外檢查點結構還保存了檢查點SCN被分配時的線程的數量和線程中當前RBA地址顯示的存儲線程的RBA地址(相對於存儲SCN作為線程的隱式的指針)使得在單實例環境中日志序列和歸檔日志名稱更容易找到

  檢查點在一段時間內可以支持高達個重做日志線程總計字節長

    日志歷史

    線程檢查點

  每個激活的線程在控制文件中的記錄中都包含了一個檢查點結構我們稱之為線程檢查點這個檢查點中的SCN字段就是線程檢查點SCN還有線程序號和RBA字段指明了這個線程檢查點跟哪個SCN相關

  線程檢查點結構在實例每次對其線程發出檢查點操作時被更新(見檢查點發生時跟該實例相關的線程會把重做日志裡記錄的小於該線程檢查點SCN的重做記錄保護的髒數據寫入到聯機數據文件中

  線程檢查點事件保證了該線程的重做日志中所有小於該線程檢查點SCN的重做記錄對應的髒數據都被寫入到磁盤(注意到如果該線程關閉了重做日志裡就沒有SCN比線程檢查點SCN還小的記錄

  實例恢復的時候要保證對應線程的所有重做日志都應用到數據文件中因為線程檢查點SCN以前的重做日志已經被應用了所以實例恢復可以保證在啟動重做日志進程時只要從線程檢查點SCN開始應用直至重做日志文件的尾部所有線程的重做日志都被應用

    數據庫檢查點結構

  數據庫檢查點結構就是所有打開的線程中線程檢查點SCN最小的那個線程檢查點數據庫檢查點線程的序號當前線程檢查點是數據庫檢查點的那個線程的序號被記錄在控制文件的數據庫信息部分

  因為每個實例都保證對應線程檢查點SCN以前的重做日志保護的髒數據已經寫到數據文件中並且數據庫檢查點SCN是所有線程中線程檢查點SCN最小的所以可以說所有實例中在數據庫檢查點SCN以前的重做日志記錄所保護的髒數據都被寫到數據文件中換句話說是數據庫所有聯機數據文件都在數據庫檢查點時發生了檢查點操作這就是一個實例檢查點了對應線程時用數據庫檢查點更新了所有聯機數據文件檢查點(見下面)的基本原理(見

    數據文件檢查點結構

  數據文件檢查點結構指的是每個數據文件的頭部包含的檢查點結構其中的SCN字段就是數據文件檢查點SCN

  由前面而知針對每個數據文件在其檢查點SCN以前的所有線程的重做日志保護的髒數據都已經被寫入到數據文件每個聯機的數據文件會把它的檢查點SCN記錄在控制文件中但這個值可能跟數據文件頭部的檢查點SCN不一致Oracle恢復層設計成能接受這種不一致當實例失敗發生在更新數據文件頭部的檢查點之後提交控制文件事務之前時二者沒有及時同步造成不一致(注控制文件事務是數據庫內部機制獨立於Oracle事務層指的是保證對控制文件任意大的更新都能夠自動被提交

  數據文件檢查點執行時(見數據文件頭部的檢查點結構會被更新並且保證所有線程產生的重做日志記錄在該檢查點SCN以前對應的髒數據都已經被寫入到磁盤上了

  線程檢查點事件(見)保證了所有線程產生的所有SCN在檢查點SCN以前的重做日志記錄對應的髒數據都被寫入到磁盤了線程檢查點事件可能會推進數據庫檢查點(如在單實例環境中或該線程的檢查點最舊了)如果數據庫檢查點推進了新的檢查點將更新所有聯機數據文件的檢查點結構(熱備份中的數據文件除外見第節)

  介質恢復時要保證對即將恢復的數據文件把任一個線程產生的重做日志記錄都要應用上去由前面知對即將恢復的數據文件來說每個線程產生的重做日志在該數據文件檢查點SCN以前的重做日志都已經得到應用介質恢復在重新應用日志時只需要從數據文件檢查點SCN開始支持恢復結束點用戶指定結束的SCN或時間點等(不完全回復)又或者是所有線程的結束點(完全恢復)

  因為數據文件檢查點保存在數據文件的頭部中所以在數據文件的備份中同樣也存在如果是熱備份產生的備份熱備份保證了當數據文件處於熱備份狀態時即使在復制要備份的數據文件過程中數據庫要更新該數據文件上的髒數據數據文件中所有數據庫的版本跟數據文件頭部的檢查點結構的版本是一致的都是在熱備份開始那一刻時的版本

    結束SCN

  每個數據文件在控制文件的記錄中都有一個字段叫結束SCN如果該數據文件是脫機狀態或只讀的該結束SCN的值表示對該數據文件不會有再比這個結束SCN更大的重做記錄如果該數據文件是聯機的並且有一個實例打開了數據庫結束SCN就會被設置為無限大(注值為xffffffffffff)結束SCN用於介質恢復時告訴重做程序在該數據文件上應用重做日志時到了這個SCN時就停止這保證了在數據庫打開的狀態下恢復一個脫機的數據文件時介質恢復能停下來

  不管數據文件脫機或者只讀結束SCN都會被設置為具體的SCN不管脫機操作時立即(因為I/O錯誤導致或者因為數據文件所在表空間被立即脫機)還是臨時的正常的(數據文件所在表空間正常脫機)不過在數據文件被立即脫機時不會發生數據文件檢查點(見並且對應的髒數據都丟失了因此在將該脫機文件變成聯機時介質恢復需要重新應用重做日志直至結束SCN介質恢復不需要應用結束SCN以後的重做日志因為就不存在這樣的重做日志如果結束SCN等於數據文件檢查點SCN那麼該數據文件就不需要恢復

    檢查點計數

  在數據文件頭部和數據文件在控制文件的記錄部分都有一個檢查點技術檢查點計數是用來判斷數據文件或者控制文件是否是過時的(從一個備份中恢復出來的)

  每次發生線程檢查點事件時檢查點計數都會遞增從而即使數據文件的檢查點沒有被推進時檢查點計數也會增加線程檢查點事件時數據文件檢查點沒有被推進的原因可能是數據文件處於熱備份狀態或者它的SCN比要更新的檢查點SCN值還要新(如數據文件時新增的或者剛經歷了一次數據文件檢查點事件)

    表空間干淨結束SCN

  數據字典TS$有兩列表示 表空間干淨結束SCN(注i中是SCNWRP和SCNBAS組合表示)它表示表空間是在這個SCN時被脫機或者設置為只讀如在對數據文件發出檢查點操作後(見數據文件檢查點SCN被記錄到TS$中作為表空間干淨結束SCN這樣的表空間在數據庫以重置日志方式打開後不需要被刪除(見在介質恢復時以重置日志方式打開日之前這種表空間會處於脫機狀態重置日志後表空間也不需要恢復允許被直接設置為聯機狀態或讀寫狀態重置日志後建議立即備份表空間

  當把一個脫機且干淨的表空間置為聯機或者可讀寫時表空間干淨結束SCN會被設置為(中間可能短暫性被設置為無窮大)立即或臨時性的將表空間置為脫機狀態tablespaceclenstop SCN也會是

  一個在TS$中表空間干淨結束SCN為非零的表空間被認為在那個SCN時是干淨的指的是該表空間包含了直至那個SCN的所有的重做記錄保護的數據沒有大於那個SCN的重做日志記錄存在如果該表空間的所有數據文件都是脫機時刻的狀態或者只讀的那在將表空間置為聯機狀態時是不需要恢復的注意到表空間干淨結束SCN同數據文件在控制文件中的記錄的結束SCN是有區別的結束SCN只是表明該數據文件沒有超過結束SCN的重做日志記錄但並沒有暗示該數據文件已經包含了結束SCN以前的所有重做日志記錄所保護的髒數據

  表空間干淨結束SCN存放在TS$中而不是控制文件中所以可以得到重做日志的保護並且處於正確的狀態如在一個不完全恢復後(見該表空間的狀態依然正確它的值也不會隨著使用了備份的控制文件更重要的是這種SCN的存在使得該表空間在以重置日志方式打開數據庫後依然可以存在因此不完全恢復期間的脫機了的表空間可以在以重置日志方式打開數據庫後直接置為聯機狀態或設置為可讀寫如果沒有表空間干淨結束SCN就沒有辦法知道該表空間不需要被重置日志拋棄的重做日志記錄那時唯一可選的辦法就是將該表空間脫機

    數據文件脫機范圍

  數據文件在控制文件中記錄了脫機時的SCN和脫機結束時的檢查點二者界定了該數據文件不需要重做日志的范圍因此介質恢復的時候可以直接跳過該范圍的重做日志這個特性幫助恢復了一個已經脫機了或者設為只讀了很長一段時間的數據文件變成聯機或可讀寫

  當一個數據文件從脫機狀態變為聯機狀態時(或從只讀變成可讀寫時)脫機范圍設置規則如下脫機起始SCN取的是該表空間的表空間干淨結束SCN脫機結束檢查點取的是數據文件設置為聯機(或可讀寫)時的數據文件檢查點

    重做日志

  重做日志描述了對數據塊的所有變更這一節主要描述數據庫打開的時候寫日志時的一些操作

    原子修改

  數據庫最基礎的操作就是以原子的方式修改數據塊前台進程想修改一個或幾個數據塊時首先得獲取對數據緩沖區中包含該塊的緩存的一個排它訪問權限然後構建改變向量重做日志緩沖區中分配空間保存重做記錄重做緩沖區位於SGA中LGWR進程定時將重做日志緩沖區中的重做記錄寫入到重做日志文件中以釋放空間當重做日志滿了的時候LGWR就要做日志切換注意在重做日志緩沖區中分配空間的同時也會在重做日志文件中分配空間重做日志緩沖區空間分配後前台進程負責構建重做記錄此後才能修改數據緩沖區中的數據塊然後當重做日志緩沖區中的重做記錄寫到重做文件中才算數據庫變更完成恢復保證重做日志中記錄的變更都會應用到數據文件中(除非是不完全恢復)

    寫日志優先

  寫日志優先是一個緩沖區執行協議用來協調寫髒數據到數據文件中和寫重做日志記錄到重做日志文件的順序根據寫日志優先協議在DBWR進程將髒數據寫入到數據文件中之前LGWR進程必須先將對應的重做日志記錄寫入到重做日志文件中

  注意寫日志優先協議跟提交時寫日志協議是獨立的(見

  同時注意寫日志優先協議只適用於將那些在數據緩沖區中的髒數據寫入到數據文件這種情形不適用於直接路徑寫(如由直接路徑讀導致的)

  寫日志優先協議保證了數據文件中沒有一種變更在重做日志文件中沒有記錄不惜以失敗為代價

  寫日志優先協議還保證了所有數據塊都在先寫完重做日志並保證能夠回滾的情況下才寫到磁盤的使得如果提交失敗的時候可以回滾所有修改這裡的重做信息其實就是回滾段的重做信息

  寫優先協議在數據庫事務層保證事務的原子性起了很大作用

    事務提交

  事務提交時會分配一個SCN並且建立一個包含那個SCN提交的重做日志記錄當事務所有的重做記錄(包括commit對應的重做記錄)都寫到磁盤上的重做日志文件中時commit過程才算結束因此commit會強制日志刷新到磁盤上至少截止到commit的重做記錄這就是通常說的logforceatcommit

  恢復就是設計成這樣在事務commit的時候只需刷新重做記錄到重做日志而不用刷新該事務修改的所有髒數據為的是在即使失敗的情況下也能保證事務持久性這就是通常說的nodatablockforceatcommit

    線程檢查點事件

  線程檢查點事件發生時會將該線程的重做記錄中SCN小於指定值的重做記錄保護的髒數據都刷新到數據文件中完成後該線程在控制文件中的線程檢查點結構會被更新

  線程檢查點事件開始時首先是得到一個SCN初始化一個檢查點結構然後該實例的數據緩沖區中所有髒數據都被打上做檢查點的標識DBWR分階段將這些標識的髒數據寫入到數據文件中當所有髒數據都寫入到數據文件中時檢查點結構中的SCN被更新為前面得到的SCN然後用該檢查點更新該線程在控制文件中的檢查點記錄

  一個線程檢查點事件可能會或者不會推進數據庫檢查點當只有一個打開的線程時新的線程檢查點也同時是新的數據庫檢查點如果有多個打開的線程並且當前線程就是數據庫檢查點所聯機程當前線程的檢查點事件會推進數據庫檢查點因為新的檢查點SCN是最近分配的很有可能比其他打開狀態的線程的檢查點SCN要大數據庫檢查點SCN將推進到新的最小的線程檢查點SCN不過如果當前線程原有檢查點不是數據庫檢查點那麼該線程的檢查點事件不會推進數據庫檢查點

  數據庫檢查點推進時每個數據文件頭部的檢查點計數也會增長並且每個數據文件只要不是在熱備份中或者沒有更高的檢查點SCN(如新增的數據文件或者剛恢復的數據文件)數據文件頭部的檢查點都會推進到跟新的數據庫檢查點一致數據文件頭將寫入磁盤同時數據文件在控制文件中的記錄的檢查點SCN也會更新為新的數據庫檢查點SCN

    聯機模糊位

  你或許已經注意到在數據緩沖區中還存在一些比那些標識了檢查點的髒數據還要新的修改它們是聯機程檢查點事件後產生的因此產生時的SCN要高於數據文件頭部的線程檢查點SCN這些髒數據可能因為很多原因也被寫到數據文件中這時我們稱這個數據文件是聯機模糊的就是說它包含了一些檢查點SCN以後的變更一個聯機的數據文件在數據庫打開的時候常常是聯機模糊的

  聯機模糊狀態是通過設置數據文件頭部的一個聯機模糊位來標識的所有數據文件的聯機模糊位是在數據庫打開的時候設置的另外一個脫機的數據文件在解除脫機狀態時也會設置它的聯機模糊位

  聯機模糊位在最後一個實例正常關閉或者立即關閉的時候被清除其他清除該狀態位的場景有(i)崩潰恢復結束(ii)當介質恢復進程到了崩潰恢復結束時做檢查點(刷新所有髒數據)(見(iii)當將數據文件臨時或正常脫機時(如在檢查點之前將文件脫機)(iv)當發出開始熱備份指令(見

  在節我們將見到如果有數據文件是聯機模糊的那麼以重置日志方式打開數據庫將會失敗

    數據文件檢查點事件

  數據文件檢查點事件發生時所有實例(所有打開的線程)都將強制刷新指定SCN之前的所有重做記錄保護的髒數據完成後數據文件頭部的檢查點將被更新別寫到磁盤上

  數據文件檢查點事件發生在如開始熱備份(見第節)和將表空間的部分數據文件正常脫機時

    日志切換

  當實例需要產生一些重做記錄而重做日志中卻沒有充足的空間時就會發生日志切換首先是找到一個聯機的重做日志文件候選

  候選日志條件一是該重做日志文件的狀態不是激活的即它不能是崩潰或實例恢復還需要的重做日志文件換句話說覆蓋它不能造成實例恢復需要的重做記錄丟失強制執行的原則是聯機重做日志不能被重用除非該線程檢查點已經超出該重做日志最後一筆重做記錄對應的檢查點因為實例恢復時是從當前檢查點SCN開始根據RBA再查找聯機重做日志而日志切換的候選日志是實例恢復不需要的則說明當前檢查點SCN應該超出候選日志的最高SCN如果不是這樣說明候選日志上正在進行檢查點操作(還沒有做完)此時不能切換到日志上

  候選日志條件二是它已經完成歸檔了當然前提是數據庫必須運行在歸檔模式下如果沒有則通知歸檔進程進行歸檔歸檔未完成之前此時也不能切換到該日志上

  當日志切換完成時在新的日志上會有個線程檢查點操作期望在檢查點操作能在下一次日志切換來臨前完成

    歸檔中的日志切換

  在並行服務器環境中由於每個線程都獨立切換日志各個線程中的日志的起始SCN值並不一樣但是對於啟用狀態的線程的歸檔日志的SCN范圍要求大致相同這保證每個線程的最後一筆歸檔日志都是當前日志如果一個啟用狀態的線程的日志未歸檔且含有一個比較老的SCN(當該線程的實例活動很少時常發生)它將不能用主庫的歸檔日志來把備庫站點恢復到一個更高的SCN尤其是該日志沒有包含重做日志時

  解決這個問題的方法就是當其他線程的當前的日志明顯比當前線程的歸檔日志還要落後時就強制其他線程做日志切換如果其他線程是打開的則有一個鎖專門促使緩慢的實例去切換日志並歸檔如果其他線程是關閉的則當前活動的線程代替它做日志切換並進行歸檔你會注意到這會導致一種現象就是一個線程處於啟用狀態但卻從未使用卻有一堆只有文件頭的歸檔日志該強制歸檔時的SCN會維護在控制文件中Oracle會努力去對所有小於或等於該SCN的聯機日志進行歸檔通常SCN最小的日志會首先被歸檔

  命令ALTER SYSTEM ARCHIVE LOG CURRENT 用於手動對所有啟用狀態的線程的當前日志進行歸檔它強制所有啟用的線程無論打開還是關閉的切換新日志然後歸檔所有舊的日志直至發出命令前所有的重做日志都被歸檔才返回這個命令保證了熱備份恢復時所需要的所有日志都得到歸檔它還保證了主庫及時往備庫傳送歸檔日志以防止災難

    線程打開

  實例打開數據庫的時候會打開一個線程用於產生重做日志這個線程在數據庫被掛載選定的實例初始化文件中有一個參數可以指定實例打開的線程號如果未指定實例就從公共的線程中選擇一個線程上有個鎖用於防止兩個實例打開同一個線程實例打開線程的時候會在控制文件中設置線程打開標志位每個活動的實例都持有一組線程打開鎖(分別為LGWRDBWRLCKLCK等持有)實例關閉的時候會釋放這些鎖用於實例檢測並行服務器環境中其他實例是否活動同時實例打開線程的時候的檢查點將作為線程檢查點如果是數據庫首次打開則該檢查點也是數據庫檢查點同時推進所有聯機數據文件的檢查點注意線程打開的時候也可能會發生一次日志切換

    線程關閉

  實例關閉數據庫的時候或者一個線程被實例/崩潰恢復線程都會關閉線程關閉的第一步就是保證不在產生重做然後將該線程產生的日志保護的所有髒數據都刷新到磁盤上

  數據庫正常關閉的時候這個是由線程檢查點事件完成最後一次檢查點時的SCN就是線程關閉時的SCN最後線程在控制文件中的線程打開標志位被清除

  如果線程是被實例恢復結束而關閉重做程序將從該線程最近一次線程檢查點記錄開始對數據文件應用該線程對應的重做日志直至日志的結束一旦該線程重做日志保護的所有髒數據都刷新到數據文件後線程檢查點推進到線程結束時的檢查點正常的線程檢查點可能會推進數據庫檢查點如果這是最後一個關閉的線程數據庫在控制文件中記錄的檢查點線程值將設置為該線程即使線程已經關閉

    線程啟用

  要打開一個線程首先得啟用該線程這保證在介質恢復的時候能夠找到該線程的重做日志線程可以以公共或私有的方式啟用一個私有的線程只能被在初始化文件中系統參數指定的實例打開這跟回滾段的使用有點類似一個線程啟用後必須至少有兩組重做日志組其中一個重做日志組是當前正在使用的它的下一個SCN記錄是無限大以保證新的SCN永遠落在當前日志的SCN范DATABASE ENABLE THREAD)該線程啟用記錄用於介質恢復應用新的線程的重做記錄也就是說介質恢復打開了另外一個線程數據庫創建的時候會自動啟用一個線程從而避免了先有雞還是先有蛋的爭論這也是說如果一個數據庫不是運行在並行服務器環境下就不需要再啟用新的線程

    線程禁用

  如果線程長時間不用就禁用它這也就是說介質恢復不需要該線程的重做日志記錄當一個線程被禁用的時候它的重做日志文件可能會被刪除線程禁用之前必須先關閉它這保證所有髒數據都刷新到磁盤上新的SCN會作為該重做日志的下一個SCN日志文件頭也會記錄該SCN同時表明這個線程已經被禁用了這個新分配的SCN很重要它保證了該線程任一個檢查點中的SCN在該線程的一個重做日志中也意味著禁用一個線程的時候必須打開另外一個線程不能禁用所有線程

    熱備份

  熱備份指在數據文件正在使用的時候對其進行復制復制的過程中DBWR也在進行因此備份可能得到一些不一致的備份

  a一些數據塊可能比其他塊的時間要早

  b一些數據塊的SCN可能比數據文件頭部的SCN還要早

  c一些塊可能包含了一個重做記錄的部分更新其他的部分可能在這個數據文件上或者其他數據文件上

  d一些數據塊可能會被損壞因為塊的頭部和尾部是在不同的時間復制的

  上面的這種復制方式得到的備份集在還原後和介質恢復的時候是沒有用的介質恢復時會從數據文件上的開始熱備SCN(見中第二步)直至恢復過程結束(完整或不完整的恢復)這樣數據文件從事務上講是一致的

  熱備份一共有三個步驟

  a執行命令ALTER TABLESPACE BEGIN BACKUP

  b調用操作系統的復制工具復制該表空間下所有數據文件

  c執行命令ALTER TABLESPACE END BACKUP

    BEGIN BACKUP

  BEGIN BACKUP命令實際對表空間的所有數據文件進行 下列操作(不需要按順序)

  在每個數據文件頭部設置了熱備份模糊標志位表明該數據文件處於熱備份狀態帶有這種標記的數據文件頭表明這個備份是熱備份標志的目的是凍結這個數據文件頭部的檢查點(停留在begin backup命令發出那一刻的SCN)這個值作用在於當備份被還原時介質恢復能從足夠早的SCN開始重新應用重做日志因為我們不能保證數據文件頭首先被復制因此熱備份期間要將數據文件頭的檢查點凍結支持熱備份結束這個標准也凍結了數據文件的檢查點(以及在控制文件中的記錄的檢查點)以免被線程檢查點更新版本後數據文件頭新增了一個備份檢查點以接收原本屬於被凍結的檢查點該接收的更新

  做了一個數據文件檢查點操作捕獲了開始熱備時候的檢查點信息包括開始熱備的SCN當數據文件被檢查點時所有實例都要刷新跟該數據文件有關的髒數據如果此時需要實例恢復檢查點將等待恢復完成再繼續在開始備份的時候對數據文件進行檢查點操作保證了在熱備份期間只有在發出熱備份命令之後的時間裡修改的塊可能會被寫到數據文件上

  [跟平台有關可選]熱備份後開始數據塊的前鏡像記錄記錄過程中所有實例將每個要修改塊的完整的塊而不是修改向量記錄到重做日志中這是為了防止恢復中遇到零碎的塊(不一致的塊)這多發生在數據塊的大小比操作系統的塊要大的時候更新數據塊導致前一部分和後一部分分別在不同的時間被復制在熱備份後恢復進程可以利用重做日志中的記錄的完整前鏡像構建數據塊

  設置數據文件頭部的檢查點跟開始熱備份時刻的檢查點一致並凍結它直至發出END BACKUP命令

  清除了數據文件的聯機模糊位標志在熱備份期間該狀態位一直是被清除的直至發出END BACKUP命令

    復制文件

  復制是由操作系統的工具來完成管理員必須保證復制操作發生在BENGIN BACKUPEND BACKUP之間或者文件沒有使用的時候

    END BACKUP

  當發出END BACKUP命令時各熱備的表空間的數據文件將發生下列操作

  還原了數據文件的聯機模糊標志位

  在重做日志中寫入一筆該數據文件結束熱備份的重做記錄這筆重做記錄只會在介質恢復中有用記錄了熱備份開始時刻的SCN(該SCN跟數據文件頭部被凍結的檢查點的SCN一致)這筆記錄也標志著熱備份期間的重做日志的結束介質恢復時讀到這個熱備份結束標記就知道熱備份期間產生的重做日志都被應用到了數據文件上然後介質恢復就清除熱備份模糊標志位這個標志位能防止不完全恢復錯誤的選擇在BEGIN BACKUP和END BACKUP時間點之間停止如果一個不完全恢復在這樣的點停止了可能會導致數據文件不一致因為備份時的復制過程可能已經包含了這個時間點之後的變更將會見到當數據文件的熱備份標志位還在時以重置日志的方式打開數據庫將會失敗

  清除熱備份模糊標志位

  停止數據塊前鏡像記錄

  推進數據文件的檢查點到當前數據庫檢查點這彌補了熱備份期間線程檢查點推進了數據庫檢查點卻無法推進數據文件頭檢查點(因為被凍結了)

    崩潰的熱備份

  當有數據文件處於熱備份狀態時正常關閉啟動了熱備份的實例或者最後一個實例都不被允許還有將熱備的數據文件正常脫機或臨時脫機也不行這是為了保證結束熱備份的標志記錄能正常產生也告訴了管理員他們忘了發出END BACKUP命令

  當熱備份期間實例崩潰了或者以abort方式關閉時所有熱備份中文件的熱備份模糊標志位還處於被設置狀態文件頭檢查點還處於被凍結狀態仍舊是熱備份開始時刻的檢查點即使數據文件的數據塊跟數據檢查點一致文件頭看起來像剛還原的備份需要介質恢復且跟開始熱備份的檢查點一致崩潰恢復還是會失敗報需要介質恢復因為它發現數據文件處於熱備份崩潰的狀態中而這個文件起始不需要介質恢復但是需要修正一下文件頭部取消崩潰熱備份狀態

  介質恢復可以恢復和打開有數據文件處於崩潰熱備份狀態的數據庫版有個更好的選擇就是用命令ALTER DATABASE DATAFILE END BACKUP將數據文件結束熱備份狀態數據文件可以從視圖V$BACKUP中查看之所以能這樣做緊接著這個命令後崩潰恢復就可以打開數據庫注意ALTER TABLESPACE END BACKUP命令在數據庫沒有打開的時候是不能用的因為數據庫只有在打開的時候才能通過數據字典找到表空間對應的數據文件

    實例恢復

  實例恢復用於恢復崩潰失敗或者並行服務器環境中的實例失敗所以實例恢復既可以指崩潰恢復也可以指並行服務器環境中的實例恢復(只要有一個存活的實例就可以恢復其他一個或多個失敗的實例)

  實例恢復的目標就是還原失敗實例在數據緩沖區中的數據塊並關閉還開著的線程實例恢復只用聯機歸檔日志和當前聯機數據文件(不需要還原歷史備份)實例恢復一次只能恢復一個線程它從該線程最近的線程檢查點開始恢復直至線程的結束

    檢測是否需要實例恢復

  當Oracle內核發現一個實例死掉而對應線程在控制文件中的線程打開狀態位還是開的時候會自動進行實例恢復實例恢復在下面兩種情形下自動進行

  崩潰失敗後第一次打開數據庫

  並行服務器個別實例(不是所有的)失敗了

  在並行服務器環境中存活的實例通過下列方法檢測到一個或多個實例失敗需要進行實例恢復

  存活實例的一個前台進程在將數據文件中的塊讀入數據緩沖區時檢測到Invalid block lock 這個多發生在另一個實例已經將該塊讀入數據緩沖區並用鎖保護了該塊髒數據然後該實例失敗了

  存活實例的前台進程通知它的SMON進程查看失敗的實例

  存活實例可以申請死亡實例的線程打開標志鎖從而發現該實例已經死亡

  存活實例的SMON進程得到一個死亡實例的列表和錯誤的數據塊列表當實例恢復結束後這些列表中的鎖都會被清掉

    ThreadataTime Redo Application

  實例恢復同一時間只能處理一個線程因此同一時間也只能恢復一個實例在處理下一個線程之前實例恢復會將每個線程的所有重做日志(從該線程的線程檢查點開始到線程結束)應用到數據文件上這個算法的正確性取決於同一時刻只有一個實例能修改數據緩沖中的塊在不同的實例修改同一塊之間該塊會被寫回磁盤因此實例恢復時從磁盤中讀入數據緩存中塊只需要某一個線程就夠了那個線程包含了該塊最新的修改日志

  實例恢復總是能夠只要該線程的聯機日志就可以完成崩潰恢復首先處理線程檢查點最低的那個線程按照線程檢查點SCN遞增的順序進行恢復保證了數據庫檢查點是由每個恢復過的線程推進的

    當前聯機數據文件

  檢查點計數器用於校驗數據文件是當前聯機數據文件而不是歷史備份如果數據文件是從備份中還原出來的則需要首先進行介質恢復

  當數據文件是從備份中還原出來的時候即使只要聯機重做日志就可以恢復介質恢復仍然不可避免理由是崩潰恢復在處理每個線程的時候都是應用該線程檢查點以後的重做日志崩潰恢復能夠用這種重做算法是因為每個塊只需要最多一個線程的重做日志

  然而如果在還原的備份上進行恢復時無法斷定要哪些線程的重做日志因此一次一個線程的算法在這種情況下不起作用在備份上恢復需要將多個線程的重做合並如把數據文件檢查點後的所有重做日志按照SCN遞增的順序合並各個線程中的重做日志這種線程合並重做算法只有介質恢復才會用(見第節)

  崩潰恢復如果使用線程合並重做算法恢復一個備份即使數據文件的檢查點跟數據庫檢查點一致依然會失敗原因是在所有的線程中崩潰恢復會丟失數據庫檢查點和最高的檢查點之間的重做日志相比之下介質恢復會從數據文件檢查點開始應用重做程序而且即使崩潰恢復也從數據文件檢查點開始應用重做程序還是會失敗因為它只會去找聯機重做日志而所有線程可能都已經將其重做日志歸檔了並重用了聯機日志

  如果使用了命令STARTUP RECOVER 崩潰恢復會因為數據文件需要介質恢復而失敗此時在數據庫打開之前會自動調用RECOVER DATABASE進行介質恢復

    檢查點

  實例恢復不會嘗試應用數據文件檢查點之前的重做日志(數據文件頭部的檢查點SCN不能決定是否需要實例恢復)

  實例恢復讀取從數據文件檢查點之後到線程結束之際的重做日志找到該線程分配的最大的SCN用於關閉線程和推進線程檢查點實例恢復結束後也會推進數據文件檢查點和檢查點計數器

    崩潰恢復完成

  崩潰恢復完成時所有數據文件的聯機模糊位熱備份模糊位介質恢復模糊位都將被清除掉然後在重做日志中寫入一筆特殊的重做記錄標記崩潰恢復的結束這條記錄用於通知介質恢復在恢復時何時可以清除數據文件的聯機模糊位和熱備份模糊位

    介質恢復

  介質恢復用在丟失或損壞數據文件或者丟失了控制文件的情形介質恢復將還原的數據文件恢復成當前數據文件還能夠恢復數據文件異常脫機時沒有來得及做檢查點操作丟失的變更介質恢復使用歸檔日志和聯機日志跟實例恢復不同的是介質恢復必須由命令顯式調用

    什麼時候做介質恢復

  由節知道數據文件如果是還原的備份在打開前都要進行介質恢復即使是應用聯機日志就可以恢復的另外一種情形就是數據文件異常脫機沒有做檢查點操作不做介質恢復數據庫是無法打開的需要介質恢復的數據文件也不能聯機數據庫沒有被任何實例打開的時候介質恢復只能在脫機的數據文件上恢復即使有崩潰恢復的時候也要在打開數據庫顯示調用介質恢復命令此時崩潰恢復可能沒有什麼做的但還是會自動運行有時候介質恢復可能發現沒有日志要應用就會報個錯不需要介質恢復即該文件不需要恢復

  如果當前控制文件丟失了將一個備份控制文件還原了介質恢復就必須做了這是所有數據文件都聯機的時候還要介質恢復的一個例子

    線程合並重做程序

  介質恢復應用重做日志時用的是線程合並的重做算法即它要同時應用所有線程的重做日志按SCN遞增的順序合並重做日志在還原的數據文件上應用介質恢復的過程跟在聯機數據文件上應用崩潰恢復的過程的不同在於崩潰恢復同一時刻只會應用來自一個線程的日志因為同一時刻數據文件上的塊只需要最多一個線程的重做日志(同一時刻只有一個實例可能修改該塊)在還原的備份上則無法猜測跟該塊有關的線程數目通常介質恢復時需要同時讀取所有線程的重做日志然後按照SCN遞增的順序合並重做日志注意這個算法依賴於數據塊的變更各個線程都是按SCN遞增的順序記錄的(並行服務器環境中)

    還原備份

  在數據庫關閉或者數據文件脫機的情況下可以將該數據文件的備份還原注意決不能在數據文件還在訪問的情況下還原每次都數據文件頭時都會校驗數據文件頭部的檢查點計數和數據文件在控制文件中的檢查點計數以檢測是否發生這種非法操作

    介質恢復命令

  介質恢復命令有三種

  RECOVER DATABASE

  RECOVER TABLESPACE

  RECOVER DATAFILE

  這三個命令的根本區別在於恢復的數據文件集合不同三個命令都用同樣的標准決定每個數據文件是否要做介質恢復每個數據文件上都一個排它鎖介質恢復程序開始恢復前會先申請獲得這個鎖如果得不到就觸發一個錯誤這可以防止兩個恢復會話同時恢復同一個數據文件以及防止對一個在使用的數據文件進行介質恢復

    RECOVER DATABASE

  這個命令用來恢復所有聯機數據文件如果所有實例都正常關閉並且也沒有數據文件被還原這個命令會觸發一個no recovery required的錯誤當有實例已經打開了數據文件時這個命令也會報錯因為該實例已經持有所有的鎖

    RECOVER TABLESPACE

  這個命令用來恢復指定表空間上的所有數據文件為了將表空間名轉換成具體的數據文件名數據庫必須先打開這意味著這個表空間及其所有數據文件在數據庫打開前得先脫機才能進行介質恢復如果該表空間的所有數據文件都不需要介質恢復時會觸發一個錯誤說沒有文件需要介質恢復

    RECOVER DATAFILE

  這個命令用來恢復指定的數據文件無論數據庫是否打開只要能獲得該數據文件上的介質恢復鎖即可當一個實例已經打開數據庫的時候則只能在脫機的數據文件上做介質恢復

    開始介質恢復

  介質恢復時開始查找介質恢復起始SCN如所有要恢復的數據文件的文件頭中最低的檢查點SCN注意如果一個數據文件的檢查點SCN落在它的脫機SCN范圍內(見)則會引發一個異常此時該數據文件的脫機結束SCN將替代文件頭檢查點SCN參與計算介質恢復起始SCN

  然後每個激活的線程(指在介質恢復開始SCN那一刻處於激活狀態的線程)都會分配一個緩沖區用來讀取重做日志每個文件的文件頭的檢查點SCN被保存下來用來確保在這個SCN以前的重做日志不需要應用結束SCN(控制文件中記錄的)也被保存下來如果是無窮大則取最大的結束SCN用來告訴介質恢復在何處停止超出這個SCN的重做日志不需要應用(見介質恢復結束時之前結束SCN為無窮大的數據文件會在該結束SCN處做一個檢查點操作(而不是在介質恢復結束點)這使得一個干淨脫機或者只讀的數據文件在跟它的表空間干淨結束SCN處進行檢查點操作

    應用重做日志介質恢復檢查點

  每個在介質恢復起始SCN處激活的線程(見)都打開了一個日志如果該日志是聯機狀態就會自動被打開如果該日志是歸檔狀態就會提示用戶輸入日志名稱除非是自動恢復所有線程中的重做日志按照產生的順序被應用在需要的時候還會切換線程

  有個例外就是在基於取消的不完全恢復(見)或者是備份的控制文件的恢復(見按序列順序計算出的下一個聯機日志如果在磁盤上會自動被應用否則會提示輸入它的完整路徑

  在日志分界點介質恢復會執行一個檢查點操作髒數據會被寫入到磁盤數據文件頭檢查點推進因此在此之前的重做日志不需要再重新應用介質恢復的檢查點還可能發生在介質恢復結束時會對介質恢復開始時一些結束SCN為無窮大的數據文件在結束SCN處做檢查點操作

    介質恢復和模糊狀態位

    介質恢復模糊位

  數據文件頭部的介質恢復模糊位用來表示由於在進行介質恢復該數據文件可能包含比數據文件頭部檢查點SCN還要晚的數據變更介質恢復模糊位在介質恢復開始的被設置通常來說在介質恢復對數據文件頭發生一次檢查點時該狀態位可以被清除當介質恢復成功結束或失敗時該狀態位才算永久清除將見到在不完全恢復後以重置日志方式打開數據庫如果還有數據文件的介質恢復模糊位被設置將會打開失敗

    聯機模糊位

  介質恢復在碰到一個崩潰恢復結束標記(或者一個立即脫機的標記發生在數據文件還沒有做檢查點操作就脫機)介質恢復會在下一個介質恢復檢查點清除數據文件頭的聯機模糊位和熱備模糊位(如果被設置)

    熱備份模糊位

  在碰到一個結束熱備份標記(或者一個崩潰恢復結束標記)介質恢復會在下一個介質恢復檢查點操作時清除熱備份模糊位在不完全恢復後以重置日志方式打開數據庫時如果有數據文件熱備份模糊位或其他模糊位被設置打開將失敗這防止了不完全恢復在熱備份開始和結束中間時間點結束時還能以重做日志方式成功打開數據庫在這樣的時間點結束不完全恢復將會導致數據文件處於不一致狀態因為還原的備份可能包含該結束點和熱備份結束點之間的數據庫變更

    線程啟用

  當一個實例啟用一個新線程的時候會在該線程的重做日志中寫入一筆線程啟用記錄當介質恢復碰到這樣的記錄時就重新分配一個重做日志緩沖區打開新的線程的重做日志開始應用它的重做日志

    線程禁用

  線程被禁用的時候它的當前日志被標記為線程結束介質恢復應用完該重做日志後會釋放它的重做日志緩沖區並停止查找該線程的重做日志

    結束介質恢復(完整的介質恢復)

  每個線程的當前日志(也是最後一個)都會有個線程結束標記完整的介質恢復(相對於不完全恢復)都會應用重做日志直至所有線程的線程結束處線程結束標記可以認為是沒有當前控制文件因為線程結束標記在日志頭部而不是在控制文件中的記錄中

  注意備份當前聯機日志並在後面還原是很危險的很容易導致對當前線程結束的誤判因為備份中的線程結束標記相對於當前線程結束的日志而言是過期了的

  如果正在做介質恢復的數據文件在控制文件中(假定是當前控制文件)的結束SCN是無窮大介質恢復將會聯機程結束之前停止重做程序將聯機程結束點的SCN處停止因為沒有超出這個SCN的重做日志存在了

  像中描述的那樣結束SCN是在數據文件脫機時被設置的如果沒有上面這個處理方式將不能保證數據庫打開的時候在結束SCN無窮大的數據文件上的介質恢復何時能停止

    自動恢復

  當介質恢復命令後加上AUTOMATIC選項時將會自動進行介質恢復它省去了讓用戶輸入歸檔重做日志文件路徑的麻煩前提是它們在磁盤上只要日志序號能確定日志文件名就可以根據數據庫初始化參數LOG_ARCHIVE_DEST和LOG_ARCHIVE_FORMAT計算出來除非用戶指定其他的歸檔目錄當前LOG_ARCHIVE_DEST指定的值將會被使用介質恢復開始檢查點(見)中包含(RBA字段中)線程(產生該開始檢查點的線程)初始的日志序號如果啟用了多個重做日志線程將根據控制文件中的日志歷史記錄部分將開始SCN映射到各個線程對應的日志序列號一旦第一個恢復用的日志找到了後續的日志按順序應用如果不能確定初始的日志序號用戶就得猜測直到找到正確的日志介質恢復開始檢查點中的timestamp字段值將幫助用戶決定

    不完全恢復

  RECOVER DATABASE命令可以在所有重做日志被應用前停止這種類型的恢復就是不完全恢復不完全恢復後打開數據庫必須以重置日志方式打開

  不完全恢復將數據庫恢復到指定時間點或之前的數據庫一致狀態所有後續的更新將丟失

  不完全恢復主要用於下列情形

  a因為有文件損壞必須進行介質恢復但由於某個歸檔日志或聯機日志損壞或丟失不能進行完全恢復

  b所有處於激活狀態的聯機日志都不可用因此無法進行實例恢復這個情形變成上一個情形

  c為了恢復一個用戶錯誤的操作(如刪了表或者數據等)將數據庫恢復到錯誤操作之前的一個數據庫一致的點

    Incomplete Recovery UNTIL Options

  根據停止的方式分不完全恢復有三種類型

  a基於取消的不完全恢復命令RECOVER DATABASE UNTIL CANCEL

  b基於SCN的不完全恢復命令RECOVER DATABASE UNTIL CHANGE

  c基於時間點的不完全恢復命令RECOVER DATABASE UNTIL TIME

  基於取消的不完全恢復在用戶輸入cancel(而不是日志路徑)的時候停止恢復聯機日志也不會自動被應用防止在下一個日志開始前取消如果多個線程要進行恢復可能照成某些線程的重做日志只是部分應用

  基於SCN的不完全恢復停止應用指定SCN以及更高SCN相關的重做日志因此在該SCN時提交的事務(或更晚提交)將會被回滾如果你想恢復到某個事物提交點SCN時將將該SCN值加一

  基於時間點的不完全恢復跟基於SCN的不完全恢復類似只是輸入的是時間點介質恢復根據重做日志塊頭部的時間來將該時間點轉換成SCN然後恢復到該SCN處停止

    不完全恢復和數據一致性

  為了防止不完全恢復破壞數據庫完整性所有數據文件必須恢復到同一點並且沒有任何一個數據文件擁有該點之後的數據庫變更這就要求介質恢復用的數據文件必須是從早於期望恢復的時間點之前的備份中還原出來的系統用文件頭的模糊位(見)來保證數據文件上沒有停止時間點之後的變更

    不完全恢復和控制文件記錄的數據文件

  如果要不完全恢復到某個數據文件被刪除的時間點之前則控制文件中必須有該被刪除的數據文件記錄否則無法進行恢復而現有的控制文件已經沒有該數據文件的記錄了一個可選的方法就是恢復的時候使用刪除數據文件之前時間點備份的控制文件進行不完全恢復另一個可選的方法就是用CREATE CONTROLFILE命令創建一個控制文件包含被刪除的數據文件

  不完全恢復到某個數據文件被添加之前的時間點倒沒有什麼問題新增的數據文件會在恢復後打開數據庫時被忽略為了避免介質恢復訪問該數據文件該數據文件可能被脫機

    不完全恢復後以重置日志方式打開數據庫

  不完全恢復後下一步就是以RESETLOGS選項打開數據庫其中一個影響(見第節)就是數據庫丟棄了不完全恢復中沒用用到的重做日志並且後續恢復將再也無法應用這些重做日志如果是錯誤的進行了不完全恢復(比如說又找到了丟失的日志)下一步可以以NORESETLOGS選項打開數據庫如果打開成功了則需要進行成功的完全恢復

    不完全恢復中的脫機文件

  如果不完全恢復中某個數據文件處於脫機狀態它不會被恢復如果該文件是正常脫機的表空間的一部分不被恢復就沒問題它將一直處於脫機狀態直至恢復結束否則如果以重置日志方式打開數據庫後該數據文件仍然是脫機狀態該數據文件所在表空間將不得不被刪除因為它需要重置日志之前的日志進行介質恢復通常在介質恢復之前都要去檢查V$DATAFILE中保證數據文件都聯機只有那些是正常脫機的表空間的數據文件且該數據文件將會被刪除的才能在不完全恢復中保持脫機(見

    基於備份的控制文件的恢復

  如果介質恢復時控制文件比當前控制文件舊則需要進行基於備份的控制文件的恢復(RECOVER DATABASEUSING BACKUP CONTROLFILE)這適用於控制文件是從一個備份中還原出來的或者用CREATE CONTROLFILERESETLOGS命令創建的備份控制文件

  CREATE CONTROLFILERESETLOGS命令似的控制文件是一個備份在這個命令之後只能進行基於備份控制文件的恢復只能用RESETLOGS選項打開數據庫這個命令意味著所有的聯機重做日志和控制文件備份都丟失

  相比之下命令CREATE CONTROLFILENORESETLOGS使得控制文件最新如記錄了最新的聯機日志和日志序號這個命令後介質恢復不是必需的事實上如果是以干淨的方式關閉並且沒有數據文件是從備份中還原出來的則不需要進行任何恢復此後可以以正常的方式或者NORESETLOGS方式打開數據庫

  一個備份的控制文件缺乏當前聯機日志和數據文件結束SCN的正確信息因此恢復進程不能找到聯機日志並自動應用並且恢復進程還得假定結束SCN是無窮大以RESETLOGS選項打開數據庫會糾正該信息備份的控制文件中包含的啟用的線程集合可能跟原始的控制文件也不同以RESETLOGS選項打開數據庫後也會糾正該線程集合信息

  BACKUP CONTROLFILE選項可以獨立使用也可以結合不完全恢復除非使用了不完全恢復選項所有線程都要應用重做日志直至線程結束為止這個會在以RESETLOGS選項打開數據庫時驗證

  當還原了一個備份的控制文件後即使沒有執行不完全恢復也會要求以RESETLOGS選項打開數據庫當問題僅僅是因為丟失了當前控制文件(並且存在控制文件備份)下面步驟用來避免基於控制文件的恢復和重置日志

  將備份控制文件復制到當前控制文件位置然後將數據庫啟動到MOUNTED狀態

  執行ALTER DATABASE BACKUP CONTROLFILE TO TRACE NORESETLOGS

  執行第二步中得到跟蹤文件中的SQLCREATE CONTROLFILENORESETLOGS

  第三步中的CREATE CONTROLFILENORESETLOGS命令很重要它反映了數據庫的結構信息跟丟失的控制文件一樣如在控制文件備份後添加了一個數據文件那麼CREATE CONTROLFILE 命令就要包含該數據文件的信息

  當控制文件確實是備份的控制文件時在RECOVER DATABASE命令時用BACKUP CONTROLFILE選項將會失敗這個很快就能檢測到一個跡象就是數據文件頭的檢查點計數比該數據文件在控制文件中的記錄的檢查點計數要大這個測試可能也不能測不出備份控制文件因為可能數據文件也是從備份中還原另外一個測試是驗證聯機日志文件頭部跟它們在控制文件中的記錄同樣也可能無法測出一個備份控制文件

    創建數據文件恢復一個備份中沒有的數據文件

  如果數據文件丟失或損壞了而且還沒有任何備份它可以通過重做日志和控制文件中的記錄恢復前提是滿足一下條件

  自該數據文件創建後的所有重做日志文件都可用

  包含該數據文件的信息(名稱和大小等)的控制文件可用或者可以重建

  首先用ALTER DATABASE CREATE DATAFILE 創建一個新的空的數據文件以替換丟失的數據文件然後在該數據文件上通過命令RECOVER DATAFILE 應用重做日志從數據文件創建的時間起到丟失或損壞的那一刻為止當期間的所有重做日志都應用後該數據文件就跟丟失前的那一刻狀態一致了這個方法對恢復最近創建的數據文件且沒有相應備份的情形很有用不過SYSTEM表空間的原始數據文件不能用這個方法恢復因為在數據庫創建的時候還沒有相應的重做日志保存下來

    用Export/Import進行即時恢復

  偶爾我們要撤銷某個錯誤的操作(如刪除表或者大量數據等)一個途徑就是執行一個在錯誤時間點之前的不完全恢復然後重置日志打開數據庫這種方法就導致整個數據庫不僅僅是出錯的幾個SCHEMA對象要回到一個過去的時間點

  這個方法有個副作用就是它丟棄了提交的事務任何發生在重置日志SCN後的更新都丟失了重做日志的另外一個副作用就是使得之前所有的備份對將來的恢復都沒有用

  因此將數據庫全部回滾到過去的一個時間點並不是一個可以接受的方案下面這個替代方案的副作用僅僅是將受影響的范圍限制到恢復的幾個對象

  即時不完全恢復是發生在產品數據庫的副本上稱之為用於恢復的數據庫該數據庫的初始狀態取的是產品庫發生在那個錯誤操作之前的備份在副本數據庫上可以將不相干的數據庫對象都脫機以避免不必要的恢復不過SYSTEM表空間和回滾段所在的表空間必須參與恢復以保證能以干淨的方式打開數據庫(這也說明了回滾段和數據文件應該分開存放)

  當介質恢復到錯誤時間之前的那一刻後以重置日志方式打開數據庫此時數據庫處於錯誤操作之前的一個時間點等於有了個出錯前的數據庫版本將錯誤操作影響的數據庫對象用EXPORT導出來然後導入到產品庫中在導入到產品庫之前先做以下准備

  為了恢復一個錯誤的更新操作在產品庫把受影響的表裡的數據先清除掉如truncate表數據

  為了恢復一個錯誤的刪除操作在產品庫裡先重建一下被刪除的對象(保持空數據)

  然後最重要的一步就是用IMPORT導入選擇只導入數據因為EXPORT/IMPORT是一個漫長的過程因此可以推遲到無法忍受的時間點執行同時要恢復的對象也可以通過在產品庫和副本庫間建DBLINK來隨時同步

  這種即時恢復的一個副作用就是跟要恢復的對象有關的事務一致性可能無法保證不過這個副作用可以通過把要恢復的對象面擴展到跟該事務有關的所有數據庫對象

    塊修復

  塊修復是最簡單的恢復在數據庫正常操作過程中由系統自動做的用戶幾乎感覺不到

    塊修復初始化和操作

  前台進程在修改一個緩沖區的時候調用重做程序在該緩沖區上應用改變向量時因為前台進程僵死或者觸發一個錯誤而導致緩沖區的狀態不一致塊修復就是用來修復這種緩沖區的狀態修復的過程包括(i)從磁盤上讀取該塊(ii)用當前線程的重做日志重新構建該緩沖區的一致版本(iii)將修復的塊寫回磁盤如果塊修復第一次失敗了會再嘗試第二次然後將該塊標識為邏輯損壞(將該塊的序號置為然後觸發一個塊損壞的錯誤

  塊修復使用當前線程的重做日志構建緩沖區是可行的因為

  塊修復不能使用其他線程的重做日志或者當前線程最後一次檢查點之前的重做日志

  直到當前線程檢查點超出日志聯機日志才不會重用

  數據緩沖區中的都不需要從最後一次線程檢查點之前的重做日志進行恢復

    緩沖區頭部RBA 字段

  緩沖區頭(一個內存數據結構)包含下面這些跟塊修復有關的字段

  LowRBA和HighRBALowRBA是從該數據塊最後一次塊清除操作以來應用的第一個重做日志的地址HighRBA是該數據塊最新的變更對應重做日志的地址二者結合起來描述了將該數據塊從磁盤上的版本變成最新的版本所需要的重做日志范圍

  RecoveryRBA:當執行塊修復的是PMON進程時且完成所有的塊修復可能需要很長時間就用RecoverRBA來記錄進度的

    PMON 和前台進程調用

  如果前台進程在回調重做日志程序時前台進程報錯將由前台進程執行塊修復如果前台進程不是報錯而是僵死了將由PMON進程執行塊修復

  塊修復可能需要大量的時間和I/O不過PMON進程可以有充足的時間做塊修復而忽略其他緊急任務因此對每次PMON執行塊修復使用重做日志的量有個限制(一個常量指定了每次PMON調用可以使用的重做日志塊的數量)每次PMON執行塊修復應用完最大的重做日志後都會更新數據緩沖區的RecoveryRBA字段以記錄它的進度當RecoveryRBA值達到HighRBA的值後針對這個塊的塊修復過程結束

    重置日志(RESETLOGS)

  重置日志選項用於下列情形後的第一次打開數據庫的時候

  不完全恢復

  基於備份控制文件的恢復

  CREATE CONTROLFILERESETLOGS

  重置日志的最主要的作用就是丟棄不完全恢復中沒有使用的重做日志並保證後續的恢復不再需要為此重置日志選項將所有聯機日志和歸檔日志都做廢掉副作用就是此前的所有備份對將來的恢復都沒有用了

  重做日志選項還初始化了控制文件中關於聯機日志和重做線程的內容清除了當前存在的聯機重做日志的內容如果聯機日志文件不存在就創建並重置了所有線程的日志序號

    模糊的文件

  以重做日志選項方式打開數據庫時最重要的事情就是檢驗所有的數據文件都被恢復到同一個時間點這保證了單筆重做日志的所有變更都自動應用了這點對其他的一致性原因也很重要如果所有線程重做日志都應用到所有聯機數據文件上當然可以說數據庫是一致的

  如果進行了不完全恢復有可能某個文件不是從足夠舊的備份中恢復過來通常這點可以通過檢測該數據文件的頭部的檢查點跟其他數據文件不一致而發現(脫機文件和只讀文件是例外)

  另外一種可能性就是這個文件是模糊的它可能包含了超出它檢查點SCN的變更由前面章節知數據文件頭部維護了下面這些模糊狀態位來判斷數據文件是否是模糊的

  聯機模糊位(見

  熱備份模糊位(見

  介質恢復模糊位(見

  不完全恢復後以重置日志方式打開數據庫時如果聯機數據文件的模糊被設置了則會打開失敗

  熱備份或崩潰恢復結束時會寫一筆重做日志記錄使得介質恢復可以決定何時可以清除這些模糊位重做日志會報錯如果這些模糊位還沒有被清除

  當數據文件中有一個數據文件結束恢復時的檢查點SCN跟其他數據文件的檢查點SCN(重置日志SCN)不一致時重置日志會報錯除非是下面這幾種情形

  一個數據文件恢復到一個比重置SCN要早點的SCN是可以接受的前提是該數據文件在二者之間已經沒有重做日志可以應用舉例說明該數據文件是只讀的或者脫機的且脫機范圍覆蓋了結束恢復時的SCN和重置SCN這種情形下重做日志允許該數據文件設置為脫機

  一個數據文件做檢查點的SCN比重做SCN要晚前提是它的創建SCN(在創建數據文件的時候分配的保存在文件頭中)顯示它是在重置SCN以後創建的重做日志時檢查數據字典和控制文件會發現該數據文件在數據字典中不存在但控制文件中存在結果它會從控制文件中被清除

    重置SCN和計數器

  控制文件的數據庫信息部分記錄了一個重置日志的SCN和時間點(合稱重置日志數據)重置日志數據是為了唯一標識每次重做日志打開數據庫的操作同時也保存在每個數據文件頭和日志文件頭日志文件中的重置日志數據如果跟控制文件中記錄的不一致就不能應用該日志文件中的重做日志數據文件中的重做日志數據如果跟控制文件中記錄的不一致則該數據文件就不能被訪問或者恢復除非某些特殊情形(如該數據文件所在表空間正常脫機或者是只讀的)這保證了被重置日志丟棄的重做日志不會再被應用到數據庫中也聲明了此前的任何備份對將來的恢復都是無用的因此重做日志後立即做一個備份時聰明之舉

    重置日志對線程的影響

  重置日志時每個線程的控制文件記錄都清除線程打開標記並將線程檢查點SCN設置到重置SCN因此看起來線程好像在重置SCN處關閉了控制文件中數據庫信息部分記錄的啟用的線程列表依舊可以使用此時哪個線程在恢復結束被啟用已經不重要了因為此前的重做日志已經不需要了所有線程的日志序號都被置為其中一個線程的檢查點被選為數據庫檢查點

    重置日志對日志文件的影響

  所有聯機日志都被清零意味著所有的重做日志都被永久丟棄除非在重做日志之前有備份聯機日志否則沒有任何辦法可以恢復這些聯機日志因此要恢復錯誤的清除聯機日志的唯一方案就是聯機日志有備份要恢復一個錯誤的重做日志操作必須先還原所有的數據文件控制文件和聯機日志文件然後全部恢復

  每個啟用的線程會挑選一個日志文件作為當前日志那個日志頭部將寫為日志序號注意日志文件和相關的線程是從控制文件中取出來的(用控制文件中記錄的線程號和它的日志集合)如果這個控制文件是備份的控制文件可能跟數據庫最後一次打開的時候有點區別

    重置日志對聯機數據文件的影響

  所有聯機數據文件頭的檢查點都更新為新的數據庫檢查點新的重置數據會更新到各個聯機數據文件頭部

    重置日志對脫機數據文件的影響

  脫機數據文件在控制文件中的記錄顯示需要做介質恢復不過這是不可能的因為它需要應用的重做日志的日志文件的重置數據已經不對了這意味著包含這個數據文件的表空間必須被刪除掉有一個重要的例外就是該表空間是正常脫機的或者只讀的表空間的數據文件頭中的檢查點SCN都保存在TS$中即表空間干淨結束SCN(見只要數據文件不是模糊的且是在表空間干淨結束SCN處做的檢查點在將數據文件聯機時是不需要重做日志的此時脫機文件頭部的重置數據被忽略因此在重做日志之前正常脫機的表空間是不受它脫機期間的重做日志操作影響的

    重置日志打開數據庫時對數據字典和控制文件的檢查

  重做日志打開數據庫後數據字典FILE$中記錄的數據文件會跟控制文件中記錄的數據文件進行對比這個操作在用CREATE CONTROLFILE命令後的第一次打開數據庫也會進行的不完全恢復結束的時侯數據庫中的數據文件可能跟用來恢復的控制文件中記錄 數據文件不一致使用備份的控制文件或者創建一個控制文件都有同樣的問題檢查數據字典沒有什麼危害因此每次數據庫打開的時候都會做不過正常情形下也要花時間去做沒有什麼道理

  FILE$中數據文件的入口會跟控制文件中每個數據文件號進行比較因為FILE$反映的是數據庫中的空間分配信息它是正確的控制文件中可能不對如果FILE$中不存在的而控制文件中存在的數據文件將會從控制文件中清除掉

  如果一個數據文件在FILE$中存在而在控制文件中不存在則會在控制文件中創建一個記錄占位記錄在名字MISSINGnnnn下(MISSINGnnnn中nnnn是十進制形式的文件號)MISSINGnnnn在控制文件中用來表示被脫機的文件和需要介質恢復的文件實際文件可以通過將MISSINGnnnn重命名為實際文件名的途徑來訪問

  在重置打開的時候重命名MISSINGnnnn能夠訪問實際數據文件的前提是該數據文件是只讀的或者正常脫機的換句話說如果重命名MISSINGnnnn為一個不是正常脫機或只讀的數據文件並不能使得該數據文件可以訪問因為它還需要重置打開數據庫前的重做日志來進行介質恢復如果是這樣這個表空間就得被刪除了

  如果是因為執行了CREATE CONTROLFILENORESETLOGS後打開數據庫時進行數據字典檢查而不是因為重置打開數據庫的話需要介質恢復將該數據文件更新到最新狀態

  另外一個步驟就是重復上面操作使控制文件中的數據文件記錄跟數據字典中的一致對不完全恢復而言這個就要求還原所有的備份再重新恢復了

    恢復相關的 V$ 視圖

  V$視圖包含了內核維護在內存中的數據結構的信息可以通過有SYS權限的DBA帳號訪問下面是這些跟恢復相關的V$視圖匯總

    V$LOG

  包含了控制文件中的日志組信息

  GROUP#

  THREAD#

  SEQUENCE#

  SIZE_IN_BYTES

  MEMBERS_IN_GROUP

  ARCHIVED_FLAG

  STATUS_OF_ GROUP (unused current active inactive)

  LOW_SCN

  LOW_SCN_TIME

    V$LOGFILE

  包含了控制文件中的日志成員信息

  GROUP#

  STATUS_OF_MEMBER (invalid stale deleted)

  NAME_OF_MEMBER

    V$LOG_HISTORY

  包含了控制文件中的日志歷史記錄信息

  THREAD#

  SEQUENCE#

  LOW_SCN

  LOW_SCN_TIME

  NEXT_SCN

    V$RECOVERY_LOG

  包含了需要用來完成介質恢復用的歸檔日志信息(取自於控制文件中的日志歷史記錄信息)

  THREAD#

  SEQUENCE#

  LOW_SCN_TIME

  ARCHIVED_NAME

    V$RECOVER_FILE

  包含了需要進行介質恢復的數據文件及其狀態

  FILE#

  ONLINE_FLAG

  REASON_MEDIA_RECOVERY_NEEDED

  RECOVERY_START_SCN

  RECOVERY_START_SCN_TIME

    V$BACKUP

  包含了在熱備份中的數據文件狀態信息

  FILE#

  FILE_STATUS (nobackupactive backupactive offlinenormal error)

  BEGIN_BACKUP_SCN

  BEGIN_BACKUP_TIME

    各式各樣的恢復特性

    並行恢復(v)

  並行恢復的目標是用計算和I/O的並行機制減少崩潰恢復單實例恢復和介質恢復的時間當多個磁盤上多個數據文件同時進行恢復時能有效的降低恢復時間

    並行恢復架構

  並行恢復分區做兩件事

  讀重做日志

  應用改變向量

  步驟不適合並行重做日志必須按順序讀取然後在介質恢復中合並因此這個任務由一個進程完成讀重做日志的進程

  步驟很適合並行因此應用改變向量的任務就委托給一組重做程序的從屬進程重做日志讀取進程將改變向量發送給重做程序從屬進程用的是跟並行查詢中同樣的IPC機制(進程間通訊機制)改變向量使用HASH函數利用數據塊地址做參數來分布因此每個重做程序 進程只處理分配到它的裡的改變向量重做程序從屬進程負責將數據塊讀入到緩存中檢查是否要應用改變向量如果需要就應用

  這個架構達到了數據塊讀取I/O和改變向量應用過程中的並行它允許日志讀取I/O和數據塊讀取I/O可以並行進行此外它還允許不同HASH桶中的數據塊的讀取I/O可以並行進行只要並行帶來的好處比進程管理和通信帶來的成本大就有效的縮減了恢復用的時間

    並行恢復系統初始化參數

  PARALLEL_RECOVERY_MAX_THREADS

  PARALLEL_RECOVERY_MIN_THREADS

  這兩個參數控制崩潰恢復或者介質恢復中重做程序從屬進程的數量

  PARALLEL_INSTANCE_RECOVERY_THREADS

  這個參數控制實例恢復中重做程序從屬進程的數量

    介質恢復語法變化

  RECOVER DATABASE命令新增了一個可選參數用來指定重做程序從屬進程的數量如果指定了該參數將覆蓋默認參數PARALLEL_RECOVERY_MAX_THREADS的值

  RECOVER TABLESPACE命令新增了一個可選參數用來指定重做程序從屬進程的數量如果指定了該參數將覆蓋默認參數PARALLEL_RECOVERY_MIN_THREADS的值

  RECOVER DATAFILE命令新增了一個可選的參數用來指定重做程序從屬進程的數量如果指定了該參數將覆蓋默認參數PARALLEL_RECOVERY_MIN_THREADS的值

    重做日志 Checksums (v)

  日志checksum允許日志在被歸檔之前先檢查一下是否有損壞目的是為了防止損壞的日志被復制(歸檔)這個特色將會和一個新命令 CLEAR LOGFILE 結合使用用來清除一個損壞的聯機日志而不歸檔

  一個新的初始化參數LOG_BLOCK_CHECKSUM控制了是否激活日志checksum功能如果設置了每個日志塊從緩沖區中寫入到磁盤之前都會計算一個值放在日志塊的頭部以後該checksum值將會在歸檔時或者恢復的時候被驗證如果驗證發現該日志塊的checksum值不對則會嘗試讀取該日志組的其他成員中的日志塊(如果有其他成員的話)如果所有成員都有不可避免的checksum錯誤則日志讀取操作失敗

  如果一個不可恢復的checksum錯誤導致日志不能被歸檔則該日志就不能被使用最後日志切換以及產生新的日志都會延遲如果不采取措施數據庫就會停止CLEAR LOGFILE命令提供了一種方式避免要歸檔該日志

    清除日志 (v)

  如果一個聯機日志組的所有成員都丟失或者損壞(如因為checksum錯誤或者介質錯誤等)重做日志程序可能還可以正常進行直至要重用該日志組的時候一旦所有線程的檢查點都超出了該日志則該日志可以被重用但下列情形使得重用失敗

  日志因為checksum錯誤而不能歸檔不能歸檔又導致該日志不能被重用

  日志切換失敗因為該日志不可用(如因為介質失敗)該日志可能已歸檔或未歸檔

  ALTER DATABASE CLEAR LOGFILE命令用於將一個非活動狀態的日志文件(即崩潰恢復不需要的日志文件)從上面這樣的情形中解決出來CLEAR LOGFILE允許有一個非活動狀態的日志被清除如丟棄並初始化類似於先DROP LOGFILE再ADD LOGFILE很多情形下用這個命令可以避免不必要的關閉數據庫或者重置日志

  注意CLEAR LOGFILE 不能用於清除崩潰恢復需要的聯機日志(如狀態為currentactive的日志)如果這樣的聯機日志損壞了則需要以異常方式關閉數據庫然後做不完全恢復並以重置日志選項打開數據庫

  使用UNARCHIVED選項使得日志清除過程順利進行即使是該日志文件還沒有歸檔該情形下不允許用DROP LOGFILE此外CLEAR LOGFILE允許處理下列情形

  線程中只有兩個日志組

  在介質失敗中所有日志組的成員都丟失或損壞了

  要清除的日志是一個已關閉線程的當前日志

  上面所有情形都不允許用DROP LOGFILE

  清除未歸檔的日志文件使得現有的備份都沒有用了因為恢復需要該日志文件因此建議清除未歸檔日志後立即對數據庫進行全備份此外UNRECOVERABLE DATAFILE選項在數據文件脫機且聯機前的恢復需要該日志文件時必須結合使用在CLEAR LOGFILE命令中帶上UNRECOVERABLE DATAFILE選項脫機的數據文件以及相應的表空間必須得從數據庫中刪除因為讓這個數據文件聯機時恢復的日志被清除了且沒有備份了

  前台進程在執行CLEAR LOGFILE時分為以下幾個步驟

  檢查該日志文件不是崩潰恢復需要的且可以清除

  在控制文件中將該日志標記為正在清除不需要歸檔這樣該日志文件就不能夠作為日志切換的候選成員了

  重新創建了一個新的日志文件用多塊寫將其清零(一個漫長的過程)

  重置正在清除的標記

  如果前台進程在執行CLEAR LOGFILE命令中途死掉了日志將不可用重做日志程序將會延遲數據庫可能會停止尤其是在日志切換的時候會發生因為得等待檢查點完成或者歸檔完成假如前台進程執行CLEAR LOGFILE時真的死掉了那應該重新執行一次另外一個方法就是刪除已經清除一部分的日志CLEAR LOGFILE也可能在清零時因為I/O錯誤而失敗解決的辦法就是刪除該日志並重新增加一個以替換它


From:http://tw.wingwit.com/Article/program/Oracle/201311/17808.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.