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