程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 數據庫復習7——恢復

數據庫復習7——恢復

編輯:DB2教程

數據庫復習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

有了檢查點的數據庫恢復,每次錯誤時只需恢復最近的事務即可:

反向遍歷日志,直到找到第一個<checkpoint> 繼續反向遍歷,找到最近一個未commit的事務起點<Ti, start> 從該句開始執行響應的redo和undo操作

那麼對於下面的時序圖,發生失敗時有(立即數據庫修改模式):

這裡寫圖片描述

T1被忽略 redo T2和T3 undo T4

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操作,它下一級是理想的穩定存儲器(可以假想為磁帶等層次更低的存儲介質)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved