走近數據恢復
2020-07-21 19:34:17
供稿:網友
我常常在想,如果數據庫不用考慮數據恢復,對我們這些做數據庫的人來說,日子也許將變過美好很多。
沒有一種軟件會象數據庫這樣,需要面對如此惡劣的環境。你需要考慮各種可能的錯誤和故障,例如系統斷電、磁盤損壞、甚至是地震火災。而給你的目標非常明確:不論發生何種故障,數據都不能被丟失,你可能覺得這有些小題大做,可對于許多商業應用(如銀行、火車訂票系統等)來說,這只不過是最基本的要求。
要保證每一步操作都不會丟失,既無必要,也無可能(除非你能發明一種和硬盤一樣大,和內存一樣快,同時斷電時數據不丟失的東東)。因此同并發控制中一樣,數據庫同樣也利用了事務的概念。事務是這樣一組操作,這組操作要么都做,要么都不做(我們通常把這叫做事務的原子性)。而當你決定結束一個事務時,你可能會選擇:是提交(COMMIT)這個事務,還是應該滾回(ROLLBACK)它。如果你選擇提交,那么你在這個事務中所做的全部修改都會被存入數據庫中,如果這個數據庫系統足夠強壯,它將保證:只要事務提交完成,不管今后發生何種故障,事務所做的修改都不會丟失。如果你選擇滾回,那么系統將回到事務開始的狀態,你在該事務中所做的所有修改都將丟失。如果在事務運行當中,系統發生了任何故障,你會期望它的結果應該和你滾回這個事務一樣。
恢復的本質是數據的冗余,在眾多的冗余手段中,日志(log)也許是我們最常使用的技術(盡管我們還有許多其它的選擇,如影子頁面等)。在我們對數據庫進行修改之前,系統會將數據修改前的影象(前項)和你要修改的數據影象(后項)保存在日志當中。在這個過程中,有兩點需要保證。一是日志必須先于它對應的修改被寫入數據庫,我們把這叫做先寫日志(WAL)協議,這很容易理解,想象一下,如果修改被先寫入數據庫,而系統在日志被寫入之前崩潰了,那么它將無法把該事務恢復到開始的狀態。二是在事務提交之前,必須將它的日志寫入數據庫。否則,系統無法保證后續的故障不會丟失該事務的修改。我們將不能實現我們在前面對用戶所做出的承諾。
我們繼續上文的討論,看看我們到底有哪些故障需要應付。
首先是應用故障,例如用戶不小心錯刪了一張表,或者應用破壞了完整性約束。這種故障的恢復非常簡單,對于前者,你可以顯式地滾回事務(利用日志的前項),如果你不小心提交了事務,那么問題就麻煩了,系統也許只能把它當作介質故障(利用備份)來恢復了;對于后者,系統會強迫把該事務滾回。只要數據庫還在運行,在系統看來,事務的滾回與其它正常操作并沒有什么區別。
然后是進程故障,假如在系統運行時,一個client崩潰了,或者網絡斷了(通常服務器無法區別這兩種狀態);或者服務器端的某個進程死了。這時我們恐怕得為系統配置一個監視進程,由它來定期地檢查系統狀態,恢復或清除失敗的進程(連接),同時把對應的事務滾回。我們會希望這個監視進程是所有進程的父進程,因此假設連它也死了,我們就能把這種情況歸結到后面將要討論的系統故障。
接著是系統故障,假如系統因為內部錯誤(例如數據庫或操作系統含有bug),或者發生斷電。這時緩沖區里的數據全部丟失,但幸運地是磁盤上的數據還在。因此系統在重新啟動(RESTART)后,首先重做所有事務的修改(利用日志的后項),這就讓數據庫回到了發生故障時的狀態,這時再將所有在這一點上未提交的事務滾回就完事了。注意這一過程是自動完成的,你完全不需要去關心它。
再接著是介質故障,假如磁盤出現了壞磁道,或者整個磁盤報銷了。這時上面的數據肯定已經丟失了。由于介質故障只能在你試圖再次存取磁盤時被發現,而這時故障可能早已發生。因此對介質故障的恢復需要你的參與才能完成。你必須定期地備份(BACKUP)數據庫,這樣,當介質故障發生時,你可以先用備份重新覆蓋整個數據庫(RESTORE過程),然后利用日志重做從備份那點到當前的數據庫的更新(ROLL-FORWARD過程),接下來的事情就和系統故障完全一樣了。你可能會問,那要是日志也壞了怎么辦呢?沒辦法,雞生蛋、蛋生雞,總得有個頭吧。所以你最好祈禱日志不要壞,為了保證這一點,你應該對日志文件進行鏡象,或者干脆用RAID。
除了這種恢復方式,我們還有一種叫做邏輯恢復的方式,也就是利用我們常常在用的IMPROT/EXPORT工具對數據進行備份/恢復。當然我們只把它看作是介質故障恢復的一種輔助形式(也許它更適合于恢復我們前面說的那種應用故障),因為你只能把數據恢復到你備份的那一點。
最后是災難,象發火災、被人黑了什么的,這時整個系統可能被完全破壞。你當然仍然可以對數據庫進行備份,然后把備份(磁盤)放到另一個安全的地方,但這樣做,備份以后數據庫所做的修改可能就永久丟失了。一個更為穩妥的辦法是我們在遠程建立一個備份系統,所有在本地產生的日志同時也送往這個遠程系統,為了防止網絡發生故障,本地與遠程系統之間應該同時建立幾條相互獨立的網絡連接。這聽上去好象有點超前,可實際上許多關鍵應用早就用上了。
應該明白的是,恢復畢竟是一種非常耗時的工作,特別是進行后三種故障的恢復時,數據庫對用戶不可用。而這對象銀行這樣的部門來說,損失實在太大了。因此在很多情況下,我們只把恢復看作是最后的一道防線,我們希望最好永遠也別需要用到它。因此現在就出來了各種各樣的容錯設備,象RAID、雙機系統什么的,它們會把故障發生的概率降低到一個實際上可能永不發生的程度。