rm 在包含數百萬個文件的目錄上
背景:物理伺服器,大約兩年前,連接到 3Ware RAID 卡的 7200-RPM SATA 驅動器,ext3 FS 安裝 noatime 和 data=ordered,未處於瘋狂負載,核心 2.6.18-92.1.22.el5,正常執行時間 545 天. 目錄不包含任何子目錄,只有數百萬個小(~100 字節)文件,還有一些更大(幾 KB)的文件。
在過去的幾個月裡,我們有一台伺服器出現了故障,但我們只是在前幾天才注意到它,因為它包含太多文件而無法寫入目錄。具體來說,它開始在 /var/log/messages 中拋出此錯誤:
ext3_dx_add_entry: Directory index full!
有問題的磁碟剩餘大量 inode:
Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda3 60719104 3465660 57253444 6% /
所以我猜這意味著我們達到了目錄文件本身可以包含多少條目的限制。不知道會有多少文件,但正如您所見,它不能超過 300 萬左右。不是那很好,請注意!但這是我的問題之一:這個上限到底是多少?可調嗎?在我被罵之前——我想把它調低;這個巨大的目錄引起了各種各樣的問題。
無論如何,我們在生成所有這些文件的程式碼中找到了問題,並且我們已經糾正了它。現在我堅持刪除目錄。
這裡有幾個選項:
rm -rf (dir)
我先試過這個。在它執行了一天半而沒有任何明顯的影響後,我放棄並殺死了它。- 目錄上的 unlink(2):絕對值得考慮,但問題是通過 fsck 刪除目錄中的文件是否比通過 unlink(2) 刪除更快。也就是說,我必須以一種或另一種方式將這些 inode 標記為未使用。當然,這假設我可以告訴 fsck 不要將條目放到 /lost+found 中的文件中;否則,我剛剛解決了我的問題。除了所有其他問題之外,在閱讀了更多內容之後,事實證明我可能不得不呼叫一些內部 FS 函式,因為我能找到的 unlink(2) 變體都不允許我輕鬆刪除包含條目的目錄。呸。
while [ true ]; do ls -Uf | head -n 10000 | xargs rm -f 2>/dev/null; done )
這實際上是縮短版;我正在執行的真正的一個是:導出 i=0; 時間 ( while [ true ]; 做 ls -Uf | 頭-n 3 | grep -qF '.png' || 休息; ls -Uf | 頭-n 10000 | xargs rm -f 2>/dev/null; 導出 i=$(($i+10000)); echo "$i..."; 完畢 )
這似乎運作良好。在我寫這篇文章時,它在過去三十分鐘左右刪除了 260,000 個文件。
現在,對於問題:
- 如上所述,每個目錄的條目限制是否可調?
- 為什麼用“real 7m9.561s / user 0m0.001s / sys 0m0.001s”來刪除返回的列表中的第一個文件
ls -U
,並且刪除前10,000個條目可能需要十分鐘#3 中的命令,但現在它很高興地拖著?就此而言,它在大約 30 分鐘內刪除了 260,000 個,但現在又需要 15 分鐘才能刪除 60,000 個。為什麼速度波動很大?- 有沒有更好的方法來做這種事情?不在一個目錄中儲存數百萬個文件;我知道這很愚蠢,而且在我的手錶上不會發生這種情況。Google搜尋問題並查看 SF 和 SO 提供了很多變體,
find
由於幾個不言而喻的原因,這些變體不會比我的方法快得多。但是,delete-via-fsck 的想法有什麼依據嗎?還是完全不同的東西?我渴望聽到開箱即用(或在不知名的盒子裡)的想法。感謝閱讀小小說;隨時提問,我一定會回复的。我還將使用最終文件數以及刪除腳本執行多長時間來更新問題。
最終腳本輸出!:
2970000... 2980000... 2990000... 3000000... 3010000... real 253m59.331s user 0m6.061s sys 5m4.019s
因此,在四個多小時內刪除了 300 萬個文件。
data=writeback
值得嘗試 mount 選項,以防止文件系統的日誌記錄。這應該只在刪除期間完成,但是如果在刪除操作期間伺服器正在關閉或重新啟動,則存在風險。根據這個頁面,
一些應用程序在使用時顯示出非常顯著的速度改進。例如,當應用程序創建和刪除大量小文件時,可以看到速度提高(…)。
該選項
fstab
在安裝操作中或安裝過程中設置,替換data=ordered
為data=writeback
. 必須重新掛載包含要刪除的文件的文件系統。