減少收縮 ext4 文件系統的時間
我需要縮小一個大的 ext4 卷,並且我希望盡可能減少停機時間。到目前為止,我已經完成了測試,看起來它可以被解除安裝以調整大小長達一周。有沒有辦法提前線上對文件系統進行碎片整理,這樣 resizefs 就不必移動這麼多塊?
更新: 達到這一點需要一些時間,移動了很多 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 位數字。在我的情況下,我的新文件系統大小將是 2980024320 個塊長,這樣僅處理要刪除的磁碟區域上的文件做得足夠好。讓 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]}'
據我所知, ext4fs 通過 e2fsprogs 1.42 或更高版本中的e4defrag 支持線上碎片整理(它在“完成”下列出,但狀態欄位為空;原始更新檔來自 2006 年末),當在 Linux 2.6.28 或更高版本上執行時允許您查詢目錄或可能的文件系統的狀態,並至少對單個文件進行碎片整理。截至今天,e2fsprogs的版本為 1.42.8。
不過,我不確定這是否對您有幫助,因為您想要做的似乎並不像整合磁碟上的數據那樣對數據進行碎片整理。兩者經常一起完成,但它們是截然不同的操作。
一個簡單的合併數據的方法(假設您有合理的可用空間)是將每個文件複製到同一文件系統上的一些其他邏輯邏輯,然後使用 mv 替換指向的數據inode 與新副本。這將在很大程度上取決於 ext4 分配器的詳細工作方式,但它可能值得一試,而且它應該相當容易編寫腳本。只需注意從多個位置硬連結的文件(使用這樣的方案,最簡單的方法可能是簡單地忽略連結數 > 1 的任何文件,並讓 resizefs 處理這些文件)。