Linux

10TB ext3 RAID 6 的 fsck 的主要問題(記憶體分配失敗等)

  • September 6, 2018

我最近在 linux md 軟體 RAID 6 設置中添加了第 7 個 2TB 驅動器。在 md 完成將陣列從 6 個驅動器重塑到 7 個驅動器(從 8 到 10TB)之後,我仍然能夠毫無問題地掛載文件系統。在為 resize2fs 做準備時,我解除安裝了分區並執行,並遇到fsck -Cfyv數百萬隨機錯誤的無窮無盡的流。這是一個簡短的摘錄:

Pass 1: Checking inodes, blocks, and sizes
Inode 4193823 is too big.  Truncate? yes
Block #1 (748971705) causes symlink to be too big.  CLEARED.
Block #2 (1076864997) causes symlink to be too big.  CLEARED.
Block #3 (172764063) causes symlink to be too big.  CLEARED.
...
Inode 4271831 has a extra size (39949) which is invalid Fix? yes
Inode 4271831 is in use, but has dtime set.  Fix? yes
Inode 4271831 has imagic flag set.  Clear? yes
Inode 4271831 has a extra size (8723) which is invalid Fix? yes
Inode 4271831 has EXTENTS_FL flag set on filesystem without extents support. Clear? yes
...
Inode 4427371 has compression flag set on filesystem without compression support. Clear? yes
Inode 4427371 has a bad extended attribute block 1242363527.  Clear? yes
Inode 4427371 has INDEX_FL flag set but is not a directory. Clear HTree index? yes
Inode 4427371, i_size is 7582975773853056983, should be 0.  Fix? yes
...
Inode 4556567, i_blocks is 5120, should be 5184.  Fix? yes
Inode 4566900, i_blocks is 5160, should be 5200.  Fix? yes
...
Inode 5628285 has illegal block(s).  Clear? yes
Illegal block #0 (4216391480) in inode 5628285.  CLEARED.
Illegal block #1 (2738385218) in inode 5628285.  CLEARED.
Illegal block #2 (2576491528) in inode 5628285.  CLEARED.
...
Illegal indirect block (2281966716) in inode 5628285.  CLEARED.
Illegal double indirect block (2578476333) in inode 5628285.  CLEARED.
Illegal block #477119515 (3531691799) in inode 5628285.  CLEARED.

壓縮?範圍?我從來沒有在這台機器附近有過 ext4!

現在,問題是 fsck 不斷出現以下錯誤消息:

Error storing directory block information (inode=5628285, block=0, num=316775570): Memory allocation failed

起初我能夠簡單地重新執行 fsck,它會在不同的 inode 處死掉,但現在它已確定為 5628285,我無法讓它超越它。

我花了最後幾天試圖尋找解決這個問題,並找到了以下 3 個“解決方案”:

  • 使用 64 位 Linux。/proc/cpuinfo包含lm作為處理器之一flagsgetconf LONG_BIT返回64uname -a有這樣的說法: Linux <servername> 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux。應該都很好,不是嗎?
  • 添加[scratch_files]/directory = /var/cache/e2fsck/etc/e2fsck.conf. 這樣做了,每次我重新執行 fsck 時,它都會在目錄中添加另一個 500K*-dirinfo-*和一個 8M*-icount-*的文件/var/cache/e2fsck。所以這似乎也有它想要的效果。
  • 為機器添加更多記憶體或交換空間。12GB 的 RAM 和 32GB 的交換分區應該足夠了,不是嗎?

不用說:沒有任何幫助,否則我不會在這裡寫。

自然,現在驅動器被標記為壞,我不能再安裝它了。所以,截至目前,由於磁碟檢查,我失去了 8TB 數據?!?!?

這給我留下了3個問題:

  • 我能做些什麼來修復這個驅動器(記住,在我執行 fsck 之前一切都很好!)除了花一個月時間學習 ext3 磁碟格式然後嘗試使用十六進制編輯器手動修復它?
  • 對於像 ext3 這樣流行的文件系統來說,像 fsck 這樣關鍵任務的東西怎麼可能仍然存在這樣的問題???特別是因為 ext3 已有十多年的歷史。
  • 是否有沒有這些基本可靠性問題的 ext3 替代方案?也許jfs?

(我現在在 64 位 Debian Wheezy 7.1 上使用 e2fsck 1.42.5,但在 32 位 Debian Squeeze 上使用早期版本時遇到了同樣的問題)

在玩fsck了更多之後,我找到了一些補救措施:

防止“記憶體分配失敗”錯誤

fsck似乎有記憶體洩漏的主要問題。如果它在有一些問題(真實的或虛構的)的文件系統上執行,它將一個接一個地“修復”它們(參見原始問題中的螢幕轉儲)。當它這樣做時,它會消耗越來越多的記憶體(也許保留一個更改日誌?)。幾乎沒有界限。但是,fsck可以隨時取消(Ctrl-C)並重新啟動。在這種情況下,它將從中斷的地方繼續,但它的記憶體使用被重置為幾乎沒有(一段時間)。

考慮到這一點,需要做的三件事是:

  • 使用 64 位 Linux(似乎在如何fsck使用可用記憶體方面有所不同)
  • 添加一個非常大的交換分區(我使用了 256GB,fsck執行了大約 12 個小時)
  • 頻繁中止和重新啟動 fsck(頻率取決於交換分區的大小)

注意:我不知道取消和重新啟動是否fsck會帶來任何其他危險(可能會),但它似乎對我有用。

如果出現“記憶體分配失敗”錯誤,處理由此造成的損壞(重要!)

fsck以最糟糕的方式處理Memory allocation failed錯誤:I 破壞了非常好的數據。我不確定為什麼,但我的猜測是它會將一些最終數據寫入磁碟,將它保存在記憶體中的東西(由於錯誤)同時損壞。

就我而言,最明顯的問題是當我fsck在錯誤後重新啟動時,它有時會報告損壞的超級塊。問題是:我不知道超級塊的損壞程度,特別是在它沒有報告它損壞的情況下。也許,如果在錯誤後重新啟動,它會使用在損壞的超級塊中發現的不正確的驅動器元數據進行所有進一步的檢查,並最終修復實際上並不存在的“問題”,從而破壞過程中的良好數據。

因此,如果fsck 曾經因錯誤而死Memory allocation failed,則需要使用-b參數重新啟動它以使用(希望)沒有被錯誤破壞的備份超級塊。可以使用 找到備份超級塊的位置mke2fs -n /dev/...

由於我不知道如果fsck在選擇備份超級塊的情況下死掉會發生什麼,我通常會fsdk在它到達時立即中止並在Pass 1: Checking inodes, blocks, and sizes沒有 的情況下重新啟動它-b,此時它會啟動而不會抱怨超級塊壞了。即,似乎首先要做的fsck -b是恢復主超級塊。

現在是我們一直在等待的:

如何在不讓 fsck 執行完成的情況下掛載文件系統

這是我偶然發現的:事實證明,在執行fsck -b併中止它後,一旦它列印Pass 1: Checking inodes, blocks, and sizes(在發現任何錯誤之前)文件系統處於可安裝狀態(是的!我得到了幾乎所有的數據背部!)。

(注意:可能還有另一種使用方式mount -o force,但在我的情況下不需要。)

如何首先避免所有這些問題

似乎有兩種方法:

  • 使用 ext3,但要保持完美的最新備份。然後,經常fsck使用參數執行-N。如果它顯示任何問題,請刪除整個 fs 並從備份中恢復所有內容。因為在這種情況下,人們會非常依賴備份,我建議保留備份的備份。此外,使用複制工具以某種方式確保還原不會在過程中產生隨機錯誤(在處理 TB 的數據時,萬億 r/w-ops 的 MTBF 很小)。確保也計劃由此產生的停機時間,因為多 TB 恢復可能需要一段時間……
  • **我的建議:不要使用 ext3!**fs-design 和相關工具(這裡fsck)對於實際生產使用來說不夠健壯(還沒有?)。處理記憶體錯誤的方式fsck以及錯誤首先發生的事實在我看來是不可接受的。我將從現在開始嘗試 xfs,但還沒有足夠的經驗來判斷它是否更好。

只需重建陣列並從備份中恢復數據。RAID 的重點是最大限度地減少停機時間。通過亂搞並試圖解決這樣的問題,您只會增加停機時間,從而破壞了 RAID 的全部目的。RAID 不能防止數據失去,它可以防止停機。

引用自:https://serverfault.com/questions/517634