資料庫正在操作時突然斷電,為什麼可以用日誌恢復?既然斷電了,還怎麼能寫入日誌?
01-07
因為在執行一個操作之前,資料庫會首先把這個操作的內容寫入日誌里記錄起來,然後再進行操作。這樣一來,突然斷電的時候,即使操作並沒有執行完,但是日誌在操作前已經寫好了,我們仍然可以根據日誌的內容來進行恢復。
試想一種情況:我們打算執行一個操作,應該按照先寫日誌,再執行操作的順序。假設在寫日誌的時候突然斷電,那麼這個日誌沒有寫完。這樣也不會影響資料庫的恢復,因為我們在恢復的時候,把不完整的日誌記錄忽略就好了,這些不完整日誌記錄對應的操作都還沒有開始執行,自然沒有影響。
這個資料庫恢復是指按照內部的操作日誌,使資料庫恢復「完整性」,保證一個「事務」的結果要麼已被完整執行,要被已被撤銷回滾。如果數據提交未完成,恢復是將數據撤銷回滾到上一個事務完成的時間點。
引用 http://www.bsuc.cn:8013/wlkc/db/section5/5.4.html (5.4 資料庫的恢復)部分內容另一種情況是有些己提交的事務對資料庫的更新結果還保留在緩衝區中,尚未寫到磁碟上的物理資料庫中,這也使資料庫處於不一致狀態,因此應將這些事務己提交的結果重新寫入資料庫。這類恢復操作稱為事務的重做(REDO)
wal
對於這種斷電的情況,資料庫已經考慮到了,他們會使用redo日誌,在斷電恢復後 對未完成的事物進行重新操作,我簡單介紹兩句 redo日誌,每當有操作執行前,數據真正更改前,先講相關操作寫入重做日誌。這樣當斷電,或者一些意外,導致後續任務無法完成時,系統恢復後,可以繼續完成這些更改。和redo日誌對應的undo日誌,undo日誌 叫 撤消日誌,當一些更改在執行一半時,發生意外,而無法完成,則可以根據撤消日誌恢復到更改之前的狀態。不知道題主明白了嗎?
日誌記下了斷電之前的操作步驟,恢復是恢復的這些記下來的步驟,並不是說斷電了還能寫日誌。
以oracle為例,你所有成功的操作已經寫入日誌了(先寫入日誌,再反饋給你成功與否),但不一定寫入數據文件。
所以斷電後,你之前的成功操作都是有日誌對應的。
至於你說的"斷電後寫日誌"這個神技,沒見過。資料庫,以ORACLE為例,在數據需要寫的時候,例如,你一個update 某個表的某行操作。一個修改實際上是對錶所在的數據文件的數據塊的某行記錄進行修改。這個過程1.會首先生成redo log,這個日誌記錄你update操作對xxx號數據文件,xxx號數據塊,xx行修改啥內容。2.當你update操作提交後,資料庫會此時實際上並沒有立即把那些資料庫修改了,而且會優先把這些日誌寫入磁碟。當日誌確保寫完後,資料庫才開始根據redlog日誌來更新那些數據塊。寫完後會把數據塊打個標記(SCN之類),那些應該更新而需要更新的數據資料庫一般會有個隊列來定時刷新到資料庫(減小資料庫io),這個隊列裡面的數據塊叫臟塊。3.當資料庫在修改是,還回產生undo日誌,用於回滾,undo的日誌記錄對數據塊的變更同時也會寫入redolog(除了temp外,所有數據文件的變更都會記錄redlog),如果一個操作未生效,就會被自動根據und進行回滾。4.因此,發生掉電分三種情況,①如果數據未提交,那麼原來的數據塊在資料庫啟動的時候會自動被回滾。如果undo日誌掉電沒記錄完,特可以通過redo來撤銷之前的變更,一般叫回滾。②如果掉電在提交後,臟塊未寫入磁碟,那麼資料庫同樣會根據redo日誌,對比數據塊的scn和控制文件scn還有數據文件rba之類的一些數據塊版本標記和,從重一遍之前的變更操作,這個操作因為是完成之前未完成的操作,一般叫前滾。③掉電時已經寫入磁碟,資料庫正常啟動,無需回滾或者前滾事務。綜上,資料庫利用日誌來記錄將要修改而未修改的數據塊,同時把數據塊的不通時間的版本進行編號(SCN),當數據未修改後,通過對比SCN來確保數據是否是需要的版本,配合結合REDO來進行回滾和前滾,這個操作在資料庫啟動的時候叫實例恢復。因此,一般情況下掉電都不影響資料庫的。除非資料庫的redolog出問題,例如寫入的redlog損壞了,這種情況資料庫就需要做不完全恢復,可能會丟失一些數據。所以ORACLE一般都是REDOLOG日誌組,可以分別放入不同的存儲設備,保證存儲安全。(部分存儲控制器電池沒電的時候,同時還是寫緩存的話經常會有這種redolog日誌丟失的問題)
資料庫任何寫入操作都是先寫日誌的,如果你的日誌都沒寫完,這條數據實際上就不算你寫的。所謂恢復其實是確保數據完整性,不是說你你連寫都沒寫的東西都能恢復。
比如你寫了個腳本,忽略所有錯誤,然後往資料庫寫1000000條數據,但是寫到100條的時候資料庫斷電了,這是或後面那協條寫入的時候都會報錯,但是你忽略了錯誤繼續寫,這部分是恢復不了的。。。
換句話說,資料庫任何寫入操作,第一步就是寫日誌,連日誌都沒寫完的數據,資料庫本身根本不能恢復。當然你可以通過消息隊列之類的持久化恢復。不在討論之列。只能恢復提交的事務,未提交的事務無法恢復。
斷電了是不能寫入日誌的,可能日誌寫到一半而已,會掉失很多數據,但是沒有關係,此時事務還沒有提交,這些數據丟不會影響一致性,只要保證已經提交的事務的數據沒有丟失就可以了。為了防止斷電數據丟失等情況,事務在提交前一定先要將更新的數據持久化保存到硬碟,持久化成功了才能告訴客戶端事務執行成功。伺服器重啟時,資料庫會檢查日誌的完整性,將完整的日誌的數據恢復到內存中。
日誌恢復之後,不一定是斷電那一刻的狀態,也很可能丟失了少量數據,但是沒關係,資料庫能恢復到一致性狀態
因為資料庫是准實時的持久化redo log,不存在斷電丟失的問題。
推薦閱讀:
※我的電腦所有的文件都變成.cryp1 或者 crypt格式,怎麼恢復?
※下廚房資料庫被刪除怎麼恢復?
※傳輸數據時突然把U盤拔掉,結果U盤能被識別但打不開怎麼辦?
※怎樣在 Windows 系統下存取用於 NAS 的硬碟中的 RAW 數據分區中的數據?