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