這些文章已經寫了好幾年了,可能已經過時了。在msn space和qqzone幾經輾轉之後,我想也許這些技術文章還是放在搞技術的部落格中更能幫助人。於是做了乙個艱難的決定,把這些文章一篇篇搬過來!絕對是原創的。
bio 與 stripe_head
在linux塊裝置驅動中有乙個非常重要的資料結構那就是bio。bio取代了2.4核心中的buffer head來表示塊裝置的i/o請求,以獲得更大的效能和靈活性。簡單來說,bio包含了乙個塊裝置完成一次i/o請求所需要的一切資訊。其中跟raid層相關的幾個重要欄位是:
struct block_device *bi_bdev; /* 指向實際執行i/o的裝置 */
sector_t bi_sector; /* i/o的起始扇區 */
unsigned int bi_size; /* i/o的大小 */
unsigned long bi_rw; /* 區分讀,寫*/
bio_end_io_t *bi_end_io; /* 指定i/o結束的callback函式 */
struct bio_vec *bi_io_vec; /* 這是乙個陣列,組織了參與i/o的page */
如果在今後的討論中需要用到其它字段,屆時再作介紹。
struct stripe_head在raid-5**中就對應於前面所說的stripe,在討論中,我們常常把stripe_head直接稱為stripe,但事實上 stripe_head更多的是記憶體和**方面的概念。實際上,raid-5是通過stripe_head結構來管理i/o緩衝區。在乙個stripe 上,每乙個disk都會分配乙個緩衝區。不可能raid-5裝置中的每乙個stripe都分配乙個stripe_head,所以stripe_head的 數量是有限的。在raid-5開始執行的時候,stripe_head的總數被設為nr_stripes,通常為256。下面從該結構中挑出幾個重要的來說說:
sector_t sector; /* stirpe所處的扇區,實際上就是各strip在本disk中的起始扇區,簡單的可以理解為stripe的id */
intpd_idx; /* 指示校驗strip在stripe中的位置 */
unsigned long state; /* 指示stripe的狀態 */
struct r5devdev /* 此結構用於管理每乙個disk的緩衝區 */
stripe的狀態可以處於下列乙個或多個狀態:
stripe_handle /* 該stripe需要下一步處理 */
stripe_syncing /* 該stripe在處理resync或recovery請求 */
stripe_insync /* 該stripe已經完成resync或recovery請求 */
stripe_preread_active /* 需要先預讀某些disk上的資料到緩衝區中 */
stripe_delayed /* 推遲某些預讀 */
stripe_degraded /* 該stripe有disk已經被移除 */
stripe_bit_delay /* 為了處理bitmap而作延遲 */
這裡提到了一些概念,比如resync,recoivery,預讀,bitmap。raid-5裝置建立完以後校驗資料尚未準備好,因此需要在正式寫raid-5裝置之前必須將校驗資料計算出來,否則得到的校驗資料將是錯誤的,這就需要通過一次resync請求來完成。recovery則更簡單,就是用其它資料盤和校驗盤的資料來恢復某個盤上的資料。以後會專門討論這些過程。
在乙個stripe中每乙個strip都有乙個struct r5dev結構體管理的緩衝區:
struct bio req; /* 轉送入下層裝置的bio */
struct bio_vec vec; /* 對應於req中的bi_io_vec */
struct page *page; /* 緩衝區記憶體頁 */
struct bio *toread,*towrite,*written; /* 這是3個鍊錶,分別記錄在該緩衝區上的讀,寫,已寫的bio */
sector_t sector; /* 該strip在整個raid-5裝置中的的扇區位置 */
unsigned long flags; /* 該緩衝區的狀態標誌 */
其中flag通過下列幾個狀態位來表示緩衝區狀態:
r5_uptodate /* 緩衝區記憶體頁中已經包含了當前資料 */
r5_locked /* 已經將"req"送交下層裝置 */
r5_overwrite /* 要寫的資料覆蓋了整個緩衝區 */
r5_insync /* disk狀態正常 */
r5_wantread /* 需要從下層讀出資料 */
r5_wantwrite /* 需要向下層寫入資料 */
r5_overlap /* toread中的bio有重疊 */
r5_readerror /* 有讀錯誤發生 */
r5_rewrite /* 將重構的資料寫回disk */
在 raid-5中重要的資料結構還有raid5_private_data,就是**裡常見的conf,感覺沒有必要去細說,看看在需要時再解釋。在閱讀 raid層的**時,會遇到很多變數名叫mddev,rdev,這些都是用於md管理的結構物件,mddev就是指raid-5所處的md裝置,rdev 則是組成該md裝置的子裝置指標,其型別為mdk_rdev_t。這裡可能要提一提mdk_rdev_t中,在raid-5的資料路徑中用得比較多的字段:flags。其中狀態及含義在include/linux/raid/md_k.h中都有比較詳細的說明,我要說的是我可能會將faulty==0和 in_sync==0的狀態更多的稱為spare狀態。
RAID 5(十三)其它
這些文章已經寫了好幾年了,可能已經過時了。在msn space和qqzone幾經輾轉之後,我想也許這些技術文章還是放在搞技術的部落格中更能幫助人。於是做了乙個艱難的決定,把這些文章一篇篇搬過來!絕對是原創的。前面幾篇林林總總,從raid 5原理,到錯誤,失效處理,主要還是圍繞資料處理的方方面面來說的...
raid5故障回放
故障回放 硬體 dell伺服器r720 陣列 raid 5 h310 系統 windows 2008 r2 計畫在伺服器進行sql資料庫恢復操作 sql2008 r2 資料庫備份檔案800m,在還原操作中,進行到備份檔案讀取時,sql程式一直出現假死 換到普通pc機執行此操作正常 無響應情況。並且對...
Raid5磁碟陣列raid資訊丟失資料恢復過程
北亞資料恢復中心接收到客戶的一台hp dl380 g4伺服器,伺服器使用hp smart array控制器掛載了一台國產磁碟陣列,磁碟陣列由14塊146g scsi硬碟組成一組raid5。作業系統為linux,構建了nfs ftp,作為公司內部檔案伺服器使用。由於伺服器機房進行搬遷,搬遷過程中管理員...