數據庫恢復技術
實現恢復的核心是使用冗余,也就是根據冗余數據重建不正確數據。
事務
事務是一個數據庫操作序列,是一個不可分割的工作單位,是恢復和并發的基本單位。
在關系數據庫中,一個事務是一條或多條SQL語句,也可以包含一個或多個程序。一個程序通常包含多個事務。
可以顯式的定義一個事務:
BEGIN TRANSACTION SQL 語句1SQL 語句2……
COMMIT|ROLLBACK
COMMIT是提交事務,ROLLBACK是回滾。
事務具有四個非常重要的特性,即ACID特性:
- 原子性(Atomicity) 原子性是指,事務要不全部完成,要不全部取消。如果事務失敗,會回滾到事務之前。
- 一致性(Consistency) 一致性是指,只有合法的數據才能寫入數據庫。
- 隔離性(Isolation) 隔離性是指,如果兩個事務同時執行,那么執行順序不影響執行結果。
- 持續性(Durability) 持久性是指,一旦事務提交,數據必須保存在數據庫之中。
事務一般有五種狀態,其狀態圖如下:

故障和恢復
常見的故障有四種:事務內部的故障、系統故障、介質故障、計算機病毒。
事務內部的故障有些是通過事務程序本身發現的,有些是非預期的。比如,有一個事務,從A轉賬給B。有下面的事務程序:
BEGIN TRANSACTIONBALANCE = BALANCE - 100IF (BALANCE < 0) THEN {ROLLBACK} ELSE {讀取用戶乙的余額BALANCE1BALANCE1 = BALANCE + AMOUNT寫回BALANCE1COMMIT}
如果出現了余額不足,就可以回滾,保證數據庫狀態正常,而不是只減了甲的錢卻不影響乙的錢。
有的時候事務故障是非預期的,比如運算溢出、死鎖、違反完整性限制。這類故障一般使用撤銷事務(UNDO)。
系統故障是造成系統停止運轉的任何事件,使得系統要重新啟動。這個時候,系統運行被破壞,事務非正常終止,不破壞數據庫,緩存區信息丟失。
這種系統故障可能是硬件錯誤或操作系統故障引起的。如果發生故障的時候事務未提交,那么直接UNDO未完成事務;如果已提交但緩沖區未寫入磁盤,那么進行REDO。
介質故障是外存故障,比如磁盤損壞、磁頭碰撞、操作系統潛在錯誤、瞬時強磁場干擾。一般需要裝入介質故障前某個時刻的數據副本,重做所有成功事務。
計算機病毒是人為故障或破壞。
數據轉儲
一、靜態轉儲和動態轉儲
在沒有運行事務的時候,進行的就是靜態轉儲。轉儲開始前數據庫一致,并且期間不能對數據庫進行存取和修改。這種方法實現簡單,但是降低了數據庫的可用性,因為新的事務必須等轉儲結束。
如果將轉出操作和用戶事務并發執行,進行的就是動態轉儲。轉儲期間可以進行存取修改,這種方法無需等待正在運行的用戶事務,也不會影響新事務運行。但是動態轉儲不能保證副本中數據的正確性。
因此,做動態轉儲需要把各事務的修改活動記下來,建立日志,用后備副本加上日志使得數據庫恢復。
二、海量轉儲與增量轉儲
海量轉儲是每次轉儲所有數據庫,增量轉儲是只轉儲上次轉儲后的數據。
從恢復角度來看,海量轉儲更方便,但是數據庫很大的時候增量轉儲更有效。
日志
日志是記錄事務對數據庫更新操作的文件。
一、日志文件的格式和內容
一般來說,日志有記錄為單位,也有以數據塊為單位。
以記錄為單位的日志內容包含:
- 事務開始標記
- 事務結束標記
- 事務所有更新操作
這樣的稱為一個日志記錄。每條日志記錄又分成
- 事務標識(表明事務種類)
- 操作類型(插入、刪除、修改)
- 操作對象(記錄內部標識)
- 更新前數據的舊值(對插入操作來說是空)
- 更新后數據的新值(對刪除操作來說是空)
以數據塊為單位的日志文件,每條日志記錄內容是
- 事務標識
- 被更新的數據塊
二、日志文件的作用
日志文件可以進行事務故障恢復、系統故障恢復、協助后備副本進行介質故障恢復。
下面是一個用靜態轉儲副本和日志文件進行恢復的例子。

在靜態轉儲的基礎上,得到一個一致性副本,然后發生故障。那么重新運行所有事務,就可以把數據庫恢復到一致狀態。
三、登記日志文件
登記日志的次序需要嚴格按照并行事務執行的時間次序。必須先寫日志文件,后寫數據庫。
這是因為,如果在二者之間故障發生了,先寫數據庫,這個記錄就無法恢復;如果先寫日志,只需要做一次UNDO。
四、故障的恢復
(1)事務故障
恢復事務故障,首先反向掃描文件日志,然后查找事務的更新操作。接下來,對事務更新操作進行逆操作,把更新前的值重新寫入。
繼續掃描文件日志,查找事務其它操作,直到讀到事務開始標記。
(2)系統故障
首先正向掃描日志,然后建立兩個隊列。第一個叫做REDO隊列,第二個叫做UNDO隊列。REDO隊列存放故障發生前的已經COMMIT的事務,UNDO隊列存放尚未發生的隊列。
對UNDO隊列的事務統一進行UNDO處理,也就是在數據庫中儲存更新前的值;對REDO隊列的事務統一做REDO處理,把更新后的值寫入數據庫。
(3)介質故障
介質故障一般先重裝數據庫,然后重做已完成的事務。
一般來說,可以裝入最新的后備數據庫副本。靜態副本可以直接裝入,動態副本還需要裝入轉儲時的日志文件副本。
介質故障恢復往往需要DBA的介入,重裝最近轉儲的副本和各日志文件副本,執行系統提供的恢復命令。
檢查點
之前的日志恢復技術,搜索日志需要大量時間,同時REDO也大量耗費了時間。因此,具有檢查點的恢復技術是常見的技術。
建立檢查點一般有兩種,可以是按固定時間間隔定期建立,也可以按照某種規則,比如日志文件寫滿一半建立一個檢查點。檢查點實際上就是一個標記,事務 T T T在檢查點之前提交,那么 T T T已經寫入了數據庫,無需進行REDO。

T3、T5在故障發生時未完成,所以撤銷;T2、T4在檢查點之后提交,需要REDO;T1則無需REDO。
用檢查點的恢復步驟如下:
- 找到最后一個檢查點記錄的地址
- 由檢查點記錄得到正在執行的事務ACTIVE-LIST,建立UNDO和REDO LIST,并把ACTIVE LIST放入UNDO LIST
- 正向掃描日志文件,新開始的事務放入UNDO LIST,提交事務放到REDO LIST
- UNDO LIST進行UNDO,REDO LIST進行REDO
數據庫鏡像
DBMS自動把整個數據庫或其中關鍵數據復制到另一個磁盤上,由DBMS保證鏡像數據和主數據庫的一致性。在出現介質故障的時候,可以由鏡像磁盤繼續使用,同時DBMS利用磁盤數據進行恢復,而無需重裝數據庫副本。

同時,在沒有出現故障的時候,數據庫鏡像也可以用于并發操作,如果一個用戶對數據加排他鎖,其他用戶可以讀鏡像數據庫的數據。
頻繁的復制數據會降低效率,所以一般只對關鍵數據和日志進行鏡像。