第六章 錯(cuò)誤恢復(fù)和日志

先來(lái)回顧下,之前的幾個(gè)一致性的概念。
首先是STRICT CONSISTENCY,就是要求所有的操作都嚴(yán)格的按照機(jī)器上的WALL CLOCK來(lái)排序。那么所有并行的進(jìn)程的操作都會(huì)有序。這在分布式的情況下是做不到的。

和這個(gè)最接近的是SEQUENCE CONSISTENCY。它的經(jīng)典實(shí)現(xiàn)是IVY,用自定義的TOTAL ORDER來(lái)取代WALL LOCK。我們只要認(rèn)為所有機(jī)器看到的這個(gè)順序是一樣的,就是符合SEQUENCE CONSISTENCY。

下一級(jí)是 RELEASE CONSISTENCY,他確保的是鎖的釋放和獲取之間是被SEQUENCE CONSISTENCY 保護(hù)的。而沒(méi)有鎖的地方順序是可以不一樣的。

EVENTUAL CONSISTENCY, 是為了性能考慮,而引入。它所保證的是你可能看到的結(jié)果可能是舊的,但未來(lái)某個(gè)時(shí)刻會(huì)得到新的。

下面我們就來(lái)討論如果一臺(tái)機(jī)器掛了怎么辦?
機(jī)器掛了的最大問(wèn)題是狀態(tài)會(huì)丟失,所以我們要做的是保證重啟之后狀態(tài)和原來(lái)一樣并且掛的這個(gè)事使得整個(gè)執(zhí)行進(jìn)入一個(gè)不合理的狀態(tài)。
不合理的狀態(tài)就是個(gè)中間狀態(tài),不是ALL OR NOTHING。 是操作了一半留個(gè)爛攤子的狀態(tài)。這個(gè)中間的狀態(tài)是非法的。


image.png

下面舉個(gè)1000塊的轉(zhuǎn)賬的例子。為了性能考慮,一開(kāi)始都是緩存在內(nèi)存里,最后寫入磁盤。


image.png

這個(gè)例子會(huì)發(fā)生A的錢被減掉,B卻沒(méi)拿到。
第一種思路是用備份的頁(yè)再上面改完,然后用一個(gè)指針轉(zhuǎn)移(這個(gè)操作為原子)來(lái)實(shí)現(xiàn)原子效果。


image.png

這種思路有2個(gè)問(wèn)題。
1.可能原子操作點(diǎn)不是很好找
2.TX可能不是由一個(gè)人完成的。


image.png

解決思路是LOG


image.png

這個(gè)LOG 可以在舊狀態(tài)時(shí)用來(lái)REDO,恢復(fù)出新?tīng)顟B(tài)。
也可以在新?tīng)顟B(tài)時(shí)UNDO,恢復(fù)成舊的。

第一種設(shè)計(jì),使用一個(gè)LOG文件來(lái)記入所有TX。LOG是用APPEND的方式追加在最后。

image.png

為什么要使用一個(gè)文件,而不是每個(gè)TX一個(gè)LOG 呢?
好處是順序?qū)懕容^快。如果是多個(gè)文件,幾個(gè)TX并行,就變成了隨機(jī)寫會(huì)慢很多。


image.png

TX COMMIT之后怎么實(shí)現(xiàn)的?
WAL:寫內(nèi)存前先保證LOG在DISK上寫完了。
在一系列操作完成后,要做COMMIT ACTION,寫COMMIT標(biāo)志進(jìn)LOG


image.png

發(fā)生問(wèn)題,如何RECOVER。
MEMORY全丟失,可以去看LOG。
從后向前掃。首先判斷TX提交還是沒(méi)提交。有標(biāo)記的做REDO記號(hào),沒(méi)標(biāo)記的丟棄。
隨后根據(jù)有標(biāo)記的REDO,從前向后重做。
這樣全部重做,很慢,所以我們需要CHECK POINT??梢员苊釲ONG TRANSACTION FLOW。
當(dāng)一個(gè)時(shí)間點(diǎn),沒(méi)有TX在做了。我可以加入一個(gè)CHECK POINT標(biāo)志。代表之前的都OK了,那我下次REDO的時(shí)候,可以直接從CHECK POINT 開(kāi)始。

但是這個(gè)時(shí)間點(diǎn)很難找,怎么辦?
用當(dāng)前沒(méi)有正在執(zhí)行的ACTION。


image.png

下面看個(gè)例子。


image.png

現(xiàn)在CHECK POINT 開(kāi)始RECOVERY, 會(huì)記錄INPROGESS TX LOG 的位置。
會(huì)有T2 和 T4的LOG。
因?yàn)?是完成的TX。 2和4 是IN PROGESS的。

這個(gè)CASE是一些操作先放內(nèi)存,每次CHECKPOINT 的時(shí)候去寫DISK。

紅色框是需要REDO, 綠色框是需要UNDO


image.png

還有一種策略,是在完成TX的時(shí)候,才去把一些結(jié)果寫進(jìn)CHECK POINT。沒(méi)有完成就什么都不寫。這樣的好處是不需要UNDO LOG。這種策略是REDO ONLY 的策略。

我們看下轉(zhuǎn)賬的例子,底層的LOG在寫什么?
這個(gè)轉(zhuǎn)賬是A 有3000塊,B有2000塊,A向B 轉(zhuǎn)1000
C有10塊,D有0塊, C向D轉(zhuǎn)10 塊。


image.png

image.png

然后找到CHECK POINT 開(kāi)始做RECOVERY


image.png

因?yàn)锳B的轉(zhuǎn)賬,已經(jīng)COMMIT了。所以在CHECK POINT的結(jié)果都寫進(jìn)DISK了。但是C 和D都是0.
首先要把沒(méi)完成的TX UNDO。所以根據(jù)CHECK POINT,找到C = C-10,來(lái)做UNDO。 C = C +10;
就UNDO好了。 隨后把T1 COMMIT 的log 在CHECK POINT之后做REDO。


image.png

為啥要同時(shí)做UNDO REDO LOG?
如果一個(gè)TX很長(zhǎng),如果只有REDO,那么TX的操作都去不了DISK,需要很多內(nèi)存去緩存。然后恢復(fù)需要全部REDO很費(fèi)時(shí)間。

如果只有UNDO,那就每個(gè)操作都要寫進(jìn)去,就更慢了。

如果沒(méi)有LONG TX,是可以用其中一種LOG的。REDO + CHECKPOINT。


image.png

這邊就是A 會(huì)被FLUSH,因?yàn)門X1 COMMIT了。B 會(huì)被REDO。 C 不會(huì)被FLUSH。


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容