一分鐘理解Redo Undo
數(shù)據(jù)庫(kù)中有一種特殊的“日志文件”叫 Redo(重做) Undo(撤銷),傳統(tǒng)意義上的日志文件是記錄系統(tǒng)運(yùn)行狀態(tài)的,主要用于系統(tǒng)工程師或者程序員排錯(cuò)。而 Reod/Undo 文件是數(shù)據(jù)庫(kù)的一部分,主要用于數(shù)據(jù)恢復(fù),保證數(shù)據(jù)的一致性和完整性。
用途
當(dāng)執(zhí)行 Insert、Update、Delete 動(dòng)作時(shí)數(shù)據(jù)庫(kù)不會(huì)真的去數(shù)據(jù)文件中執(zhí)行 I/O 操作,而是分了兩部分:
- 修改內(nèi)存中的數(shù)據(jù)(數(shù)據(jù)庫(kù)稱為 Buffer)
- 記錄 Redo Undo 日志
只有當(dāng) Buffer 達(dá)到刷新條件(比如臟數(shù)據(jù)達(dá)到一定比例)才會(huì)對(duì)數(shù)據(jù)文件進(jìn)行操作。數(shù)據(jù)庫(kù)這么設(shè)計(jì)是出于性能考慮,因?yàn)樽x寫數(shù)據(jù)文件是一次隨機(jī) I/O 會(huì)降低系統(tǒng)性能;雖然 Redo Undo 也會(huì)寫文件,但它是順序?qū)懭?,性能比較高。
這種順序?qū)懭胍话悴捎?LSM (Log Structured Merge Trees)算法,比如 Kafka,HBase、LevelDB 都采用這種結(jié)構(gòu)。
因?yàn)閿?shù)據(jù)并沒有真正的寫入數(shù)據(jù)文件,所以當(dāng)數(shù)據(jù)庫(kù)系統(tǒng)崩潰后(比如斷電、系統(tǒng)重啟、介質(zhì)錯(cuò)誤),數(shù)據(jù)庫(kù)系統(tǒng)會(huì)利用Redo、Undo 恢復(fù)數(shù)據(jù)。
如何恢復(fù)
兩個(gè)原則
- 從前向后讀取 Redo,重做所有已提交的事務(wù)
- 從后往前讀取 Undo,回滾未提交的事務(wù)
以上面操作為例,假設(shè)故障點(diǎn)發(fā)生在***個(gè) Write 之后。
數(shù)據(jù)庫(kù)啟動(dòng)后讀取 Redo 文件沒有發(fā)現(xiàn)已經(jīng)提交的事務(wù),什么也不做;讀取 Undo 文件發(fā)現(xiàn)未提交的事務(wù),恢復(fù) X=0(假設(shè) X 歷史值為 0)。
- 假設(shè)故障點(diǎn)發(fā)生在第二個(gè) Write 之后:數(shù)據(jù)庫(kù)啟動(dòng)后讀取 Redo 文件發(fā)現(xiàn)沒有已經(jīng)提交的事務(wù),什么也不做;讀取 Undo 文件發(fā)現(xiàn)未提交的事務(wù),恢復(fù) X=1,繼續(xù)回滾X=0。
- 假設(shè)故障點(diǎn)發(fā)生在 Commit 之后:數(shù)據(jù)庫(kù)啟動(dòng)后讀取 Redo 文件發(fā)生已經(jīng)提交的事務(wù),執(zhí)行 X=1,然后 X=2;讀取 Undo 文件發(fā)現(xiàn)提交事務(wù),什么也不做。
多個(gè)事務(wù)也是如此,讀者可以自行嘗試枚舉。
【本文是51CTO專欄作者“邢森”的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)聯(lián)系作者本人獲取授權(quán)】