單機(jī)存儲系統(tǒng)中的故障恢復(fù)
一、故障與恢復(fù)
本文中介紹的故障恢復(fù)主要是只單機(jī)存儲系統(tǒng)中的故障恢復(fù),就是只有一臺電腦,與之相對的是分布式存儲系統(tǒng),暫且不談。
所謂故障,就是指電腦中途突然掛掉,死機(jī),斷電等等。
所謂恢復(fù),主要是恢復(fù)內(nèi)存中的數(shù)據(jù),而不是硬盤上的,因?yàn)橛脖P上的數(shù)據(jù)是持久化的,而內(nèi)存中的數(shù)據(jù)是易失的。恢復(fù)主要通過日志來進(jìn)行恢復(fù)。
二、日志
日志主要分為兩種類型。undo日志和redo日志。日志記錄的最小單位是事務(wù),因?yàn)槭聞?wù)是原子性的,一個(gè)事務(wù)中可能會(huì)包含多個(gè)操作,一個(gè)事務(wù)中的操作要么全部執(zhí)行成功,要不全部執(zhí)行失敗。對于每個(gè)事務(wù),都會(huì)記錄日志。undo日志記錄的是事務(wù)更改前的狀態(tài),而redo日志記錄的是事務(wù)更改后的狀態(tài)。
舉個(gè)例子:X最初的值是5,你要在一個(gè)事務(wù)里將X的值更改為10。那么undo日志會(huì)記錄事務(wù)修改前的狀態(tài)<X,5>,而redo日志會(huì)記錄事務(wù)更改之后的狀態(tài),<X,10>。
操作系統(tǒng)會(huì)在內(nèi)存中執(zhí)行事務(wù),并且將內(nèi)存中的數(shù)據(jù)定期刷到磁盤中,從而實(shí)現(xiàn)將隨機(jī)寫轉(zhuǎn)化為順序?qū)憽?/p>
三、redo日志
重點(diǎn)講一下redo日志。它記錄的是事務(wù)修改后的狀態(tài)。redo日志記錄的順序是這樣的:
將redo日志以追加的方式寫到磁盤的日志文件中
將redo日志記錄的操作在內(nèi)存中進(jìn)行真正的執(zhí)行
返回操作成功或者失敗。
需要注意的點(diǎn),是對于redo日志來說,是要先將日志寫到磁盤中,才能去內(nèi)存中執(zhí)行修改。這個(gè)順序不能顛倒。當(dāng)電腦故障的時(shí)候,內(nèi)存中的東西,比如X的值會(huì)丟失,但是X得值在日志中是有記錄的,日志又是被寫到磁盤上的,斷電不會(huì)丟失,所以可以通過讀取redo日志成功找回X的值,將其在內(nèi)存中進(jìn)行恢復(fù)。
四、redo操作的優(yōu)化
我們來看一下redo操作,對于每一個(gè)事務(wù),當(dāng)事務(wù)在內(nèi)存中被真正執(zhí)行之前,都要先往磁盤里寫redo日志,但是,寫磁盤這個(gè)行為代價(jià)是很高的,并且如果同時(shí)有大量的事務(wù)要執(zhí)行,每次都要寫磁盤,那么會(huì)帶來較差的性能。
這里就要分情況了,對于一致性要求高的應(yīng)用,應(yīng)該保證每一個(gè)事務(wù)開始前,redo日志立刻刷入磁盤。但是對于一致性要求不高的應(yīng)用,則可以先將redo日志在內(nèi)存的緩沖區(qū)中先進(jìn)行緩存,等到一定的時(shí)間(如10ms)或者一定的大?。?12KB)之后再定期刷入磁盤,這種優(yōu)化方式被稱為成組提交,這樣就會(huì)提高系統(tǒng)吞吐量。但是這樣做的缺點(diǎn),是如果發(fā)生故障,被緩存在內(nèi)存中的一些redo日志也會(huì)丟失,所以可能會(huì)丟失部分操作。另外,會(huì)犧牲寫事務(wù)的時(shí)延,因?yàn)樘峤坏膶懯聞?wù)并不是立刻執(zhí)行,要先等足夠的redo日志被刷到磁盤才會(huì)開始執(zhí)行。
五、checkpoint 檢查點(diǎn)
除了內(nèi)存中緩存的redo日志要被定期刷入磁盤外,內(nèi)存中的數(shù)據(jù)也要被定期刷入磁盤,每當(dāng)內(nèi)存中的一組數(shù)據(jù)被刷入磁盤后,需要記錄日志的回放點(diǎn),以后的故障恢復(fù)只需要redo回放點(diǎn)后邊的日志即可,回放點(diǎn)之前的日志不需要被redo了,因?yàn)橄嚓P(guān)數(shù)據(jù)已經(jīng)被刷入磁盤,不會(huì)丟失。當(dāng)內(nèi)存中的數(shù)據(jù)被刷入磁盤后,會(huì)在磁盤上形成一個(gè)checkpoint文件,文件中有記錄的日志回放點(diǎn)。