MD(七)In sync標誌與resync

2021-05-24 07:28:38 字數 1600 閱讀 1970

這些文章已經寫了好幾年了,可能已經過時了。在msn space和qqzone幾經輾轉之後,我想也許這些技術文章還是放在搞技術的部落格中更能幫助人。於是做了乙個艱難的決定,把這些文章一篇篇搬過來!絕對是原創的。

關於mddev->in_sync的作用我一直只是一知半解,前段時間終於有機會將它的用法重新理解了。原來它是出於資料安全考慮的。

考慮一下這樣一種情況:乙個raid-5裝置在進行讀寫。這個時候如果計算機突然掉電,也就是說很有可能一些寫請求已經被子裝置處理,而有些可能還沒有被處理。要知道raid-5的寫請求必須要在parity也寫完以後才算寫完成。假設在同乙個stripe中,資料已經被寫入子裝置,而parity還沒有被寫入,又或者parity已經被寫入而某些資料還沒被寫入,無論哪種情況,可以想象的是,當這個raid-5再次被重組以後這個stripe中parity已經與資料不再一致。根據我以前對raid-5的分析(raid-5(十二)),parity與資料必須是同步的,否則會有資料錯誤隱患。

那我們如何去解決這個問題?最簡單的辦法就是在raid-5被重組後再次發起resync。但這種簡單的辦法開銷是很大的,因為現在的磁碟動則幾百g,要做完一次resync沒幾個小時是搞不定的,如果重組以後raid-5就立即投入處理io請求,那麼resync估計做幾天都有可能,那在這期間這個raid-5是很脆弱的。然而,就目前這種情形,在無法確定哪個stripe有隱患的情況下,發起一次全面的resync是最可靠的辦法了。

in_sync欄位就是為了確定是否需要再發起resync。在2.4的核心中,也有類似的問題,但是並沒有使用in_sync這種更為靈活的形式,其做法很死板:就是在md執行起來以後,就將md_sb_clean標誌從superblock中清掉,在md停止的時候再重新設定回去,這樣如果這時候發生非法關機,md_sb_clean標誌就是被清除的,md重組之後就知道應該要發起resync。我之所以說他死板,就是因為不管三七二十一,即使沒有讀寫,或者讀寫都已經完成了,也還會發起resync。

再回過頭來說說in_sync的靈活用法。因為只有在處理寫請求的時候有可能存在這種問題,因此,在發起寫請求的時候將in_sync設為0,表示:注意,我們可能需要resync。與此同時sb_dirty被設為1,更新superblock的操作開始執行,將superblock中的md_sb_clean標誌清掉。那什麼時候它會被設為1呢?兩個地方,一是,如果所有的寫都完成了,那麼就可以將其設為1,另乙個是md正常停止。兩種情況都回發起更新superblock,將md_sb_clean標誌恢復。這裡要羅嗦一句:以上討論都是在初始resync已經完成以後的。大家看出來了吧,發起resync的條件更為嚴格了,避免了不必要的resync。

md正常停止,就直接呼叫md_update_sb來更新superblock,沒什麼可多說的了。看看寫完成時的處理,注意md_write_end函式,並沒有我說的將in_sync置1的**,也就是說並沒有立即更新,只是根據safemode分兩種處理。safemode 2就是喚醒守護執行緒,守護執行緒會處理superblock更新;safemode 1則是延遲一段時間後再喚醒守護執行緒處理。這兩種模式的具體用途我還不是特別清楚,有興趣的話大家可以繼續深入。

到此為止,我想對md的討論告一段落,md有點凌亂,而且我還有不少地方沒有仔細讀過,不確定的地方還有不少,畢竟不如對raid-5那般熟悉,沒法做到條塊分割,如果有什麼紕漏或者謬誤,請見諒,歡迎指正。

mdadm 建立md 刪除md步驟

最近在使用mdadm建立和刪除raid裝置。但是在建立和刪除過程中會出現建立md0重啟後變成md127,刪除md127重啟後又重新出現的狀況。在網上搜尋了一下,總結如下 建立 1.mdadm cv dev md0 l5 n3 dev sdd dev sde dev sdf 2.echo device...

md5加密演算法c實現,七分注釋

經常到csdn來是查資料,每次都會有所收穫。總是看別人的感覺很不好意思,於是決定自己也寫一點東西貢獻出來。於是就有了這篇md5七分注釋。希望對用到的朋友有所幫助。記得當初自己剛開始學習md5的時候,從網上搜了很多關於演算法的原理和文本性的描述的東西,但是看了很久一直沒有搞懂,搜c的源 又很少。直到後...

判斷素數 md

素數就是乙個數被除數除了1和它本身就沒有其他被除數了 1除外,1不是素數 常規判斷素數的方法 從2遍歷如果到這個數之前都不可被整除,則該數為素數 param num return public boolean isprimenum int num for int i 2 ireturn true 通...