減少收縮 ext4 檔案系統的時間

減少收縮 ext4 檔案系統的時間

我需要縮小一個大的 ext4 卷,並且我希望在盡可能減少停機時間的情況下完成此操作。根據我到目前為止所做的測試,看起來它可以在長達一周的時間內卸載以調整大小。有沒有什麼方法可以提前在線對檔案系統進行碎片整理,以便在調整大小時不必移動這麼多塊?

更新: 要達到這一點需要一些時間,移動了相當多 TB 的數據以準備收縮,並且我一直在嘗試使用下面答案中的信息。我最終想出了以下命令行,只需稍加修改,它就可以對其處於類似情況的其他人有用。另請注意,它應該以 root 身份運行,filefrag 和 e4defrag 命令才能正常工作 - 它不會影響文件所有權。它也可以在具有多個硬連結的文件上正常工作,我有很多硬連結。

find -type f -print0 | xargs -0 filefrag -v | grep '\.\.[34][0-9]\{9\}.*eof' -A 1 | awk '/extents found/ {match($0, /^(.*): [0-9]+ extents found/, res); print res[1]}' | xargs -n 1 -d '\n' e4defrag

快速解釋以方便其他人修改/使用:

第一個「查找」指令建立要使用的檔案清單。現在可能是多餘的,或者可以用更好的方法來完成,但是在測試時我在那裡有其他過濾器,並且我將其保留為修改命令其餘部分範圍的方便位置。

接下來透過「filefrag -v」傳遞每個檔案以取得每個檔案使用的所有實體區塊的清單。

grep 尋找每個檔案使用的最後一個區塊(以「eof」結尾的行),該區塊是一個以3 或4 開頭的10 位數字。長,這樣僅處理要刪除的磁碟區域上的檔案就足夠好了。讓 grep 還包含以下行(“-A 1”)也會在下一部分的輸出中包含檔案名稱。這是其他執行此操作的人必須根據其檔案系統的大小修改命令的地方。它也可能以更好的方式完成,但這現在對我有用,而且我很懶。

awk 僅從 grep 留在 filefrag 輸出中的所有其他垃圾中提取檔案名稱。

最後調用 e4defrag - 我不關心實際的碎片計數,但它具有移動物理塊的副作用(希望進入驅動器的早期部分),並且它適用於具有多個硬鏈接的文件無需額外的努力。

如果您只想知道它將對哪些文件進行碎片整理而不實際移動任何數據,則只需關閉命令的最後一部分即可。

find -type f -print0 | xargs -0 filefrag -v | grep '\.\.[34][0-9]\{9\}.*eof' -A 1 | awk '/extents found/ {match($0, /^(.*): [0-9]+ extents found/, res); print res[1]}'

答案1

據我所知,ext4fs支援線上碎片整理(它列在「完成」下,但狀態欄位為空;原來的補丁從 2006 年底開始)到e2fsprogs 1.42 或更高版本中的 e4defrag 在 Linux 2.6.28 或更高版本上運行時允許您查詢目錄或可能的檔案系統的狀態,並且至少對單一檔案進行碎片整理。e2fsprogs截至今天,版本為 1.42.8。

不過,我不確定這是否對您有幫助,因為您想做的似乎不多碎片整理數據為鞏固磁碟上的資料。兩者經常一起完成,但它們是截然不同的操作。

整合資料的簡單方法可能假設您有合理數量的可用空間,工作是將每個檔案複製到同一檔案系統上的其他邏輯邏輯,然後使用 mv 以新副本取代 inode 指向的資料。這在很大程度上取決於 ext4 分配器的具體工作方式,但它可能值得嘗試,而且編寫腳本應該相當容易。只要注意從多個位置硬連結的文件(使用這樣的方案,最簡單的方法可能是簡單地忽略連結計數 > 1 的任何文件,並讓 resizefs 處理這些文件)。

相關內容