資料庫複習7——恢複,資料庫複習7
資料庫複習CH14 恢複13.1 恢複的概念
資料庫系統中恢複是指讓資料庫從發生某些“失敗”後的不一致的狀態恢複到正常的一致狀態的行為,恢複的基礎是冗餘(物理上冗餘,非邏輯上)
這些失敗包括了:
- 事務失敗:包括邏輯錯誤(事務不滿足某些條件不能執行)和系統錯誤(DBMS強制終止事務,如事務發生死結)
- 系統崩潰:斷電、物理硬體損壞、軟體系統(如OS)崩潰,本章假設系統崩潰不會改變非易失儲存空間
- 磁碟失敗:磁碟儲存發生錯誤,本章假設可利用檢查和監測磁碟失敗
大體上,恢複策略分成兩個步驟:
- 正常交易處理時,記錄足夠的額外資訊以供失敗時恢複
- 失敗發生後,講資料庫返回一致性狀態的動作
13.2 儲存結構和資料訪問
本小節假設討論恢複問題時的儲存結構和資料訪問模型
按系統奔潰時是否影響資料存放區,將儲存空間分成易失儲存空間(主存、cache等)和非易失儲存空間(磁碟磁帶、快閃記憶體、非易失RAM等),然後我們假設一種理想的穩定儲存空間(stable storage),發生任何失敗時都不會影響儲存資料內容
定義物理塊為儲存在非易失的磁碟上的塊,緩衝塊是為儲存在易失的主存中的塊,而私人空間是指為每個事務T分配的獨立於其他事務的虛擬儲存地區,那麼可以命名一下4種操作:
- input(A):從磁碟中載入物理塊到主存
- output(A):把主存中緩衝塊寫回磁碟
- read(X):從主存中將緩衝塊讀取到私人空間
- write(X):把私人空間中的本機複本寫回到主存
假設在事務中,DBMS在第一次訪問塊X時調用一次read操作載入到私人緩衝區,事務執行完畢時write(X)寫回主存,而事務中間的操作時都只是修改其本機複本
注意,DBMS沒有必要在每次write時調用output,這取決於OS的寫回策略
13.3 基於日誌的恢複
日誌是一組記錄在理想的穩定儲存空間上的資料庫儲存記錄,約定:
- 事務Ti開始時,日誌記錄
<Ti, start>
- 事務Ti執行write操作時,日誌記錄
<Ti, X, old_value, new_value>
- 事務Ti結束時,日誌記錄
<Ti, commit>
- 任何時候最多隻有一個事務活躍
基於日誌的恢複有兩種策略,延遲資料庫修改和立即資料庫修改
(1)延遲資料庫修改
延遲資料庫修改模式下,資料庫的修改操作僅記錄在Log中而不真正的實施write操作,直到partial committed之後才write
定義在失敗發生時的redo和undo操作:
- redo:按照Log中的
<Ti, X, old_value, new_value>
再一次寫入新值new_value
- undo:按照Log中的
<Ti, X, old_value, new_value>
撤銷新值寫入,即寫入old_value
由延遲資料庫修改模式的定義知,未記錄<Ti, commit>
的事務不執行任何恢複操作,已記錄<Ti, commit>
的事務順序地執行redo操作(其實這種模式下old_value是沒有必要記錄的)
(2)立即資料庫修改
立即資料庫修改模式和延遲資料庫修改模式相反,事務未commit之前就允許修改資料庫,write-ahead logging rule(WAL規則)規定log記錄必須在資料庫寫入之前完成
立即資料庫修改下,未記錄<Ti, commit>
的事務必須反序地執行undo操作讓資料庫返回到一致性狀態,而已記錄<Ti, commit>
的事務順序地執行redo操作
(3)檢查點
每次redo和undo時都遍曆整個Log並完成所有事務的redo和undo的話,開銷十分巨大,並且對於已經commit後output寫入磁碟的redo是沒有任何意義的,因此在Log引入<checkpoint>
語句
DBMS周期性地做檢查工作,把所有commit的事務(已write入主存)從主存中寫回到磁碟中,並在日誌中記錄一條<checkpoint>
;注意檢查時,可能某個事務還未commit
有了檢查點的資料庫恢複,每次錯誤時只需恢複最近的事務即可:
那麼對於下面的時序圖,發生失敗時有(立即資料庫修改模式):
13.4 影子資料庫
除了基於日誌的恢複,還另一種恢複策略——影子資料庫(Shadow Database),它有以下設定
- 假設任何時候只有一個事務活躍
- db_pointer指標總是指向資料庫當前的一致性副本
- 所有的update都是在資料庫的影子拷貝(shadow copy)上完成的,只有當事務partial committed之後才把影子拷貝中的副本寫入磁碟中,並且更新db_pointer
- 事務失敗時轉向db_pointer指向的一致性的資料庫,當前影子資料庫被直接刪除
- 假設磁碟不會失敗
影子資料庫的拷貝策略運用在大型資料庫上十分低效
13.5 並發事務的恢複
13.3中介紹的基於Log的恢複是針對單活躍事務而言的,下面進行更多的假設已完成對並發事務的恢複:
- 所有的事務共用一份儲存緩衝和一份日誌記錄
- 一個緩衝塊中可以有多個事務修改後的資料
- 並發控制嚴格遵循兩階段鎖(下一章詳細描述),保證未commit的事務間不可見
- 並發事務的Log可以交織在一起
- 檢查點發生時,可能有多個事務正處在活躍狀態,記錄
<checkpoint, L>
,L是檢查點發生時活躍的事務列表
- 當失敗發生時執行一下動作:初始化
undo_list
和redo_list
為空白表,倒序找到第一個<checkpoint, L>
,對於L中每一個事務的update按Log記錄反序加入undo_list
、正序加入redo_list
- 執行
undo_list
和redo_list
中的操作
13.6 緩衝管理(1)Log記錄緩衝
如果把Log緩衝在主存中,那麼當緩衝已滿或log force操作時才把Log記錄(全部)寫入磁碟(這樣多條log記錄可以一次output,減少I/O開銷),此外Log記錄緩衝還必須遵從以下約定:
- log記錄必須順序地output進磁碟
- 事務Ti只有當
<Ti, commit>
寫入磁碟後才能進入Committed狀態
- log記錄必須比相應修改後的資料先寫入磁碟
(2)資料庫緩衝
資料庫緩衝和Log記錄緩衝不一樣的是,它是分塊劃分緩衝的,當緩衝滿時是選擇緩衝塊被新塊替換(若修改需要寫回磁碟),而不整個緩衝寫回
13.7 非易失儲存空間的失敗
上述對恢複的討論僅包含易失儲存空間的部分,非易失儲存空間的恢複也利用了相似的階層式存放區器思想:增加一種dump
操作,它下一級是理想的穩定儲存空間(可以假想為磁帶等層次更低的儲存介質)