自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

數(shù)據(jù)庫系統(tǒng)實現(xiàn)-存儲管理(CheckSum&RAID)

存儲 存儲軟件
磁盤并不是萬無一失的,也可能發(fā)生故障和損壞。磁盤發(fā)生故障是災(zāi)難性的,存儲介質(zhì)的損壞如果在沒備份的情況下,基本是100%丟失數(shù)據(jù),比rm -rf 還嚴(yán)重,那么磁盤的故障有那么些?

 磁盤并不是萬無一失的,也可能發(fā)生故障和損壞。磁盤發(fā)生故障是災(zāi)難性的,存儲介質(zhì)的損壞如果在沒備份的情況下,基本是100%丟失數(shù)據(jù),比rm -rf 還嚴(yán)重,那么磁盤的故障有那么些?

[[262677]]

  1. 間歇性故障
  2. 介質(zhì)損壞
  3. 寫故障
  4. 磁盤崩潰

在這些故障的時候有哪些應(yīng)對策略和辦法?我們這章來來學(xué)習(xí)一下。

間歇性故障

當(dāng)我們嘗試從磁盤讀一個塊的時候,可能這個塊的內(nèi)容未正確的發(fā)送到磁盤控制器,這就是一次間歇性的故障,控制器會以一種辦法來判斷這個磁盤塊的好壞,如果讀的數(shù)據(jù)是壞的,控制器會嘗試再次讀取發(fā)起請求,直到讀取的數(shù)據(jù)正確位置,或者發(fā)送N次請求,然后再停止。

同樣,我們嘗試寫入一個扇區(qū),可能寫入的內(nèi)容不是原本想要寫入的內(nèi)容,唯一的辦法就是磁盤把寫入的內(nèi)容讀取出來跟磁盤控制器的內(nèi)容再比較一下。然而,跟磁盤控制器比較,其實還可以讀取寫入的扇區(qū),并且查看狀態(tài)是否為"好",如果狀態(tài)是"壞"那么就重寫,這個狀態(tài)如何產(chǎn)生的呢?這就引出了是checksum概念。

校驗和(checksum)

在說checksum之前,我們來玩?zhèn)€小游戲:

桌子上擺放了7個黑白棋子,魔術(shù)師蒙著眼睛看不見棋子。魔術(shù)師徒弟在看完7個棋子之后在右邊添加個棋子,和其他棋子并排,這個時候有8個棋子,魔術(shù)師依舊蒙著眼睛。這個時候觀眾可將其中的一個棋子翻轉(zhuǎn),或者不翻轉(zhuǎn)任何一枚。觀眾和徒弟一言不發(fā),魔術(shù)師并不知道觀眾是否翻轉(zhuǎn)棋子。

現(xiàn)在魔術(shù)師摘下眼罩,觀察8枚棋子,然后可以說出是否翻轉(zhuǎn)了棋子,識破觀眾的行為。那么魔術(shù)師是如何識破的呢?

校驗和:在磁盤的每個扇區(qū)都有幾個附加位,這個被稱為校驗和。在數(shù)據(jù)讀取的時候,如果校驗和跟數(shù)據(jù)位不符合,那么就判斷讀取錯誤。不過校驗和正確,也有可能數(shù)據(jù)是錯誤的,這個的可能性跟校驗位的長度成負(fù)相關(guān)。校驗位越長,判斷錯誤的概率越小。

校驗和是基于扇區(qū)內(nèi)所有位的奇偶性(parity),如果二進(jìn)制的集合中有奇數(shù)個1,那么數(shù)據(jù)位有奇數(shù)奇偶性并增加值為1的奇偶位。同理,如果有偶數(shù)個1,那么數(shù)據(jù)位有偶數(shù)奇偶性并且增加值為0的奇數(shù)位。

假如我們用一個字節(jié)(8bits)來判斷奇偶,并且檢測出錯誤的可能性為50%,那么出錯的概率為,1/2^8,如果用4個字節(jié)呢,則出錯率為1/2^32。相對于40億次中只有一次錯誤沒被檢測出來。

一般的在數(shù)據(jù)庫中用的是CRC或者是FNV算來進(jìn)行checksum的,在PostgreSQL中用得上 FNV-1a,我們來看看PG是如何實現(xiàn)的。

PostgreSQL-CheckSum

Postgres默認(rèn)是不開啟checksum的,在初始化數(shù)據(jù)庫的時候可以通過選項-k開啟。

  1. -k, --data-checksums use data page checksums 

使用的算法是FNV-1a,下面的地址是這個算法的詳細(xì)介紹:http://www.isthe.com/chongo/tech/comp/fnv/

核心代碼在:src/include/storage/checksum_impl.h

函數(shù)入口:pg_checksum_block

官方描述:

 

PG的實現(xiàn)跟官方的實現(xiàn)有區(qū)別,官方的實現(xiàn)為:

 

而PG在乘之前,先右移了17位,然后再xor。

計算出來的結(jié)果都存儲在頁頭PageHeaderData->pd_checksum

數(shù)據(jù)從shared_buffer刷盤以及從disk讀取block都需要計算checksum。如果只是在內(nèi)存中變更數(shù)據(jù)頁,是不需要計算checksum的。

感興趣的可以gdb跟一下看看。

再回到上面的小游戲,魔術(shù)師只要跟徒弟在之前協(xié)定好,有偶數(shù)個白或者黑,問題就解決了,這也是一種奇偶校驗的實現(xiàn)。

介質(zhì)損壞

磁盤也是有使用壽命的,當(dāng)磁盤損壞后,破壞是物理性的,數(shù)據(jù)是不可能完全的恢復(fù)回來。在上面我們介紹了如何來高效的檢測介質(zhì)的故障或讀寫的故障,但是卻沒說明如何解決這個問題。

在磁盤的扇區(qū)損壞的問題上,可以用2塊或者多塊磁盤來存儲數(shù)據(jù)。例如我們寫入內(nèi)容X,通常扇區(qū)是成對的,我們把寫入X的扇區(qū)稱作為(左拷貝)Xl和(右拷貝)Xr。讀函數(shù)可以讀取Xl或者Xr,返回一個結(jié)果w,那么w是X的真實的內(nèi)容。前提是我們通過CheckSum對Xl和Xr扇區(qū)的完整性做了排查。(這段內(nèi)容有點繞口,其實就是寫2份數(shù)據(jù)到不同的磁盤扇區(qū),然后可以任意從其中一個讀取到你想要的內(nèi)容)。

寫的策略也是一樣的,例如寫入Xl,檢查是否返回狀態(tài)為"好",如果不是,就需要不停的寫,到達(dá)若干次后,如果任然未成功,則可表示該扇區(qū)是壞的,則可以用Xr來替換損壞Xl。相反對Xr跟Xl是一樣的邏輯,重復(fù)Xl的動作即可。

讀策略是交互的,交替的讀取Xl和Xr,預(yù)先設(shè)定個很大的數(shù)字,若嘗試超過這個數(shù)據(jù),則可以確定X是無法讀取的。

RAID

上面討論的內(nèi)容其實就是RAID(Redundant Array of Independent Disk,獨立磁盤冗余陣列)。磁盤崩潰發(fā)生率一般由平均失效時間來衡量,假設(shè)磁盤平均失效時間為10年,則每年磁盤中的1/10會發(fā)生故障,為了避免這種故障,就采用了這種策略,當(dāng)一個數(shù)據(jù)盤或者冗余盤發(fā)生崩潰的時候,其他的磁盤可用于恢復(fù)故障磁盤,從而使得沒有任何數(shù)據(jù)會丟失。RAID分了很多等級,我們下面就看看不同等級的計算和使用。

RAID-1

RAID-1方案使用2塊磁盤做扇區(qū)的拷貝,一個做數(shù)據(jù)盤,一個做冗余盤,或者互換。相當(dāng)于有2份磁盤空間來存儲數(shù)據(jù)(空間浪費),任何一份失效,可以使用未損壞的進(jìn)行修復(fù),除非2塊盤同時失效。

看個例子:假設(shè)每個磁盤的使用壽命為10年,那么意味著每年的損壞率為10%。如果磁盤被鏡像,發(fā)生故障的時候我們可以利用另外一塊好的替換他。所以造成錯誤的至少要2個磁盤的數(shù)據(jù)都丟失,才能說是數(shù)據(jù)無法恢復(fù)。假設(shè)替換的時間為3個小時,這是一天中的1/8,或者是1年的1/2920,那么10年的故障率為1/29200,2塊磁盤之一平均5年發(fā)生一次故障,那么丟失數(shù)據(jù)的概率大概為5*29200=14600年。

RAID-4(奇偶塊)

RAID是以磁盤塊為奇偶校驗,假設(shè)有N塊數(shù)據(jù)盤,一個冗余盤,在冗余盤中,第i塊由所有的數(shù)據(jù)盤的第i塊奇偶校驗位組成,也就是說,所有第i塊盤的j位,包括數(shù)據(jù)盤和冗余盤,他們中間必須有偶數(shù)個1,而我們總是選取冗余盤的位讓條件為真。

假設(shè)我們有4塊盤,3個數(shù)據(jù)盤,一個冗余盤。假設(shè)一個塊只有一個字節(jié),8位。

盤1:11110000

盤2:10101010

盤3:00111000

冗余盤

盤4:01100010

在1,2,4,5,7位有兩個1,在3,4有4個1,在6和8有零個1。

利用冗余盤的位讓數(shù)據(jù)盤的奇偶校驗條件為真。

讀:

從任意一個數(shù)據(jù)盤讀取是沒有任何差別。

當(dāng)我們寫一個數(shù)據(jù)盤的一個新塊,我們不僅僅需要改變那個數(shù)據(jù)塊,還需要改變?nèi)哂啾P的相應(yīng)的塊,以保持?jǐn)?shù)據(jù)盤的奇偶性。一個樸素的辦法是讀取N個數(shù)據(jù)盤的相應(yīng)塊,取他們的摸2和,并重寫冗余盤,那么這樣就會是N+1次的磁盤I/O。

還有個更好的辦法,只關(guān)注在被寫盤的i塊的老版本和新版本,操作如下:

1、讀要要被改變的數(shù)據(jù)盤的舊值

2、讀冗余盤的相應(yīng)塊

3、寫新數(shù)據(jù)盤

4、重新計算并寫冗余盤的塊

這樣就只有4次I/O操作

摸2代數(shù)解釋

 

假設(shè)有如下三個數(shù)據(jù)盤,***個塊如下:

盤1:11110000

盤2:10101010

盤3:00111000

冗余盤:01100010

假設(shè)盤2的塊由10101010改變?yōu)?1001100,我們來求盤2上的舊值和新值的摸2和,得到

01100110,這個結(jié)果告訴我們,必須改變?nèi)哂啾P的***塊的位置,2,3,6,7的值。那么冗余盤為:0000100,如下:

盤1:11110000

盤2:11001100

盤3:00111000

冗余盤:0000100

這樣每列依舊有偶數(shù)個1

故障恢復(fù)

如果是冗余盤壞了,直接換一塊新盤,并且重新計算奇偶。如果是數(shù)據(jù)盤壞了,也是換一個新盤,不起根據(jù)其他盤重新計算它的數(shù)據(jù)。我們來看個例子:

盤1:11110000

盤2:????????

盤3:00111000

盤4:01100010

我們?nèi)∶恳涣械哪?和,可以推導(dǎo)出盤2為:

盤1:11110000

xor

盤2:00111000

=:11001000

xor

01100010

=10101010

RAID-5

在RAID-4的策略中,除非2塊盤同時損壞,否則還是能有效的保護(hù)數(shù)據(jù)。不過有個缺點,就是無論是讀和寫都需要訪問冗余盤。從上面故障恢復(fù)的例子可以發(fā)現(xiàn),恢復(fù)數(shù)據(jù)盤和冗余盤是一樣的策略,都是取其它盤的模2和。這樣,我們就不必要把一個盤做冗余盤,而把其他盤作為數(shù)據(jù)盤,相反,我們可以把每個磁盤作為某寫塊的冗余盤來處理,這種改進(jìn)稱為RAID-5。

假設(shè)我們有4塊盤,0-3。***個盤編號為0,講作為編號為4,8,12等盤的冗余,因為當(dāng)被4除時,余數(shù)為0。編號為1的盤將作為編號為1,5,9等塊的冗余。盤2是2,6,10塊的冗余,盤3是3,7,11等塊的冗余。

如果每個盤讀寫負(fù)荷一樣,如果所有的塊有相同的可能性被寫,那么對于一次寫,每個盤有1/4的機(jī)會,并且還有1/3的機(jī)會作為那個塊的冗余盤。這樣,4個盤的每個涉及寫的機(jī)會是1/4+3/4*1/3=1/2

多個盤的崩潰處理(RAID-6)

前面講的都是一塊盤的崩潰,如果涉及到多個盤的崩潰,還是無法處理的。多個盤的崩潰有一個糾錯碼原理,允許我們處理多個盤的崩潰,前提的我們有足夠多的冗余盤。這個 策略導(dǎo)致了***的RAID級別-RAID-6。這個策略是基于海明碼(Hamming code)進(jìn)行糾錯的。

我們來看個例子,一個7個磁盤的系統(tǒng),磁盤編號為1-7,前面4個是數(shù)據(jù)盤,5-7是冗余盤。數(shù)據(jù)盤和冗余盤組成的一個3*7的矩陣,如下圖:

 

如圖,請注意:

1、除了全0列之外的,三個0和1的所有可能的列都在這個矩陣中

2、冗余盤有單個1

3、數(shù)據(jù)盤至少各有兩個1

通過這個矩陣可以知道:

1、盤5是盤1、2、3相應(yīng)位的摸2和

2、盤6是盤1、2、4相應(yīng)位的模2和

3、盤7是盤1、3、4相應(yīng)位的模2和

通過這個規(guī)則,我們就能從兩個同時發(fā)生故障的磁盤崩潰中恢復(fù)。

我們從任何一個數(shù)據(jù)盤讀取數(shù)據(jù),不用理睬冗余盤

寫的話就需要考慮冗余盤。為了寫某個塊,需要計算新舊塊的摸2和,這些位以模2和的方式加入到滿足條件的所有冗余盤相應(yīng)塊中。

看個例子:

 

我們把第二個盤修改為00001111,新值和舊值的模2和為:10100101,因為盤5和6在盤行1和行2都有1

 

所以我們需要拿他們的***個塊跟剛才算出來的值10100101執(zhí)行摸2和,也就是說我們需要對這2個塊的1,3,6,8位置求反。

盤5:

10100101

xor

01100010

=

11000111

盤6:

10100101

xor

00011011

=

10111110

所以結(jié)果如下:

 

RAID-6故障恢復(fù)

假設(shè)故障盤為a和b,我們可以從下面這個矩陣中能夠把a(bǔ)和b的列不同的某個行r找到,假設(shè)a是0,而b是1.

 

然后我們通過取來自b之外所有的行r有1的磁盤相應(yīng)位模2,我們就能計算出b。計算完b,我們必須用所有其他的盤重新計算a。辦法是取該行帶1的那些其他磁盤的位摸2.

看個例子,如果盤2和盤5在同一時間損壞,如下圖:

 

我們發(fā)現(xiàn)這2個盤在列2不同,盤2是1盤5是0,那么我們用盤1,4,6來恢復(fù)盤2如下圖:

 

盤2通過計算得到:

盤1:11110000

xor

盤4:01000001

=10110001

Xor

盤6:10111110

=00001111

盤5可以用盤1,2,3來恢復(fù),如下圖:

 

盤1:11110000

xor

盤2:00001111

=11111111

xor

盤3:00111000

=11000111

這樣盤2和盤5都恢復(fù)了,結(jié)果如下:

 

關(guān)于RAID-6,磁盤的數(shù)量可以是任意次方-1,例如2^k-1,k是冗余盤,剩下的2^k-k-1是數(shù)據(jù)盤,所有冗余盤差不多是數(shù)據(jù)盤的對數(shù)增長的,并且都可以構(gòu)造成矩陣來表示。

書中只大概介紹了這幾種RAID,不過現(xiàn)在有跟多的RAID,例如:

  • RAID-0:Data Stripping
  • RAID-1:磁盤鏡像
  • RAID-0+1:RAID-0和RAID-1的結(jié)合體
  • RAID-2:帶海明嗎校驗
  • RAID-3:帶奇偶校驗并行傳送
  • RAID-4:帶奇偶校驗獨立磁盤結(jié)構(gòu)
  • RAID-5:分布式奇偶校驗
  • RAID-6:帶2種分布式存儲奇偶校驗
  • RAID-7:優(yōu)化的高速傳輸磁盤結(jié)構(gòu)
  • RAID-10:高可靠和高效磁盤結(jié)構(gòu)
  • RAID-53:高速數(shù)據(jù)傳輸磁盤結(jié)構(gòu)

總結(jié):主要是講磁盤的損壞和恢復(fù)方面的內(nèi)容,包括如何檢測損壞和如何恢復(fù),checksum是個很好的檢測手段,而磁盤的冗余是在存儲介質(zhì)損壞的時候提供有力的數(shù)據(jù)保護(hù),并且分析了幾種冗余策略。下一章我們來看看數(shù)據(jù)是如何在磁盤組織的,包括定長&變長數(shù)據(jù)的存儲,Tuple的修改(插入,刪除,跟新),跨塊的存儲和列存儲相關(guān)內(nèi)容,并且我們用C語言自己來寫個例子程序。

責(zé)任編輯:武曉燕 來源: RDBMS原理分析
相關(guān)推薦

2010-07-11 18:42:17

CassandraTwitter

2022-04-05 13:46:21

日志數(shù)據(jù)庫系統(tǒng)

2018-05-02 08:48:58

Raid存儲MySQL

2011-04-13 15:25:12

數(shù)據(jù)庫系統(tǒng)設(shè)計

2011-04-13 15:07:30

數(shù)據(jù)庫系統(tǒng)設(shè)計

2011-04-13 12:54:33

SYBASE數(shù)據(jù)庫管理

2011-02-28 17:12:20

Oracle數(shù)據(jù)庫

2011-04-13 15:17:09

數(shù)據(jù)庫系統(tǒng)設(shè)計

2011-06-07 17:01:44

2019-03-01 18:27:09

MySQL安裝數(shù)據(jù)庫

2011-02-25 13:49:12

2011-07-26 14:56:03

數(shù)據(jù)庫發(fā)展

2023-12-20 16:12:37

數(shù)據(jù)庫復(fù)制延遲

2010-09-17 20:09:25

2010-04-12 14:55:26

Oracle數(shù)據(jù)庫

2011-05-24 09:45:41

Oracle數(shù)據(jù)庫系統(tǒng)調(diào)優(yōu)

2022-08-01 18:33:45

關(guān)系型數(shù)據(jù)庫大數(shù)據(jù)

2011-09-21 11:21:00

NoSQL

2010-07-07 14:53:04

SQL Server數(shù)

2011-05-17 14:46:38

Oracle數(shù)據(jù)庫故障
點贊
收藏

51CTO技術(shù)棧公眾號