Linux伺服器作業系統快速刪除大量/大檔案
前言
注意本文說的“海量”並不是指體積大,而是指數量,比如一個目錄下有數百萬個小檔案。最近在優化伺服器時發現postfix下的maildrop目錄和clientmqueue目錄還有var目錄下發現有大量的檔案,進入這些目錄裡使用ls
命令是愚蠢的做法,而直接執行rm *
, 沒有任何反應,檔案數量也沒有減少,也就是說,在海量檔案目錄裡直接使用rm
命令進行刪除是無效的。
常規方法:
那麼正確的方法是什麼呢?有兩種方法可選:
第一種:
1 |
|
第二種:
2 |
-I{} rm {} |
一、快速刪除大量/散/海量檔案/碎片化的檔案
方法1、快速刪除大量檔案:
假如你要在linux下刪除大量檔案,比如100萬、1000萬,像/var/spool/clientmqueue/的mail郵件,/usr/local/nginx/proxy_temp的nginx快取等,那麼rm -rf *可能就不好使了。 rsync 可以用來清空目錄或檔案,如下:
1)先建立一個空目錄
mkdir -p /data/blank
2)用rsync刪除目標目錄
rsync--delete-before -d /data/blank/ /var/spool/clientmqueue/
這樣目標目錄很快就被清空了
注:其中--delete-before 接收者在傳輸之前進行刪除操作
不要忘記資料夾後的“/” 附: rsync的跟刪除相關的引數 rsync --help | grep delete --del an alias for --delete-during --delete delete files that don't exist on the sending side --delete-before receiver deletes before transfer (default) --delete-during receiver deletes during transfer, not before --delete-after receiver deletes after transfer, not before --delete-excluded also delete excluded files on the receiving side --ignore-errors delete even if there are I/O errors --max-delete=NUM don't delete more than NUM files rsync --delete-before -a -H -v --progress --stats /tmp/test/ log/
這樣我們要刪除的log目錄就會被清空了,刪除的速度會非常快。rsync實際上用的是替換原理,處理數十萬個檔案也是秒刪。
選項說明:
–delete-before 接收者在傳輸之前進行刪除操作
–progress 在傳輸時顯示傳輸過程
-a 歸檔模式,表示以遞迴方式傳輸檔案,並保持所有檔案屬性
-H 保持硬連線的檔案
-v 詳細輸出模式
–stats 給出某些檔案的傳輸狀態
方法2、快速刪除大量檔案:
直接進入到對應的目錄,然後執行命令,快速刪除大量散檔案和重複碎片化檔案
ls | xargs -n 10 rm -rf
二、快速刪除大檔案或者大容量內容檔案
方法1、快速刪除大檔案:
假如你有一些特別大的檔案要刪除,比如nohup.out這樣的實時更新的檔案,動輒都是幾十個G上百G的,也可以用rsync來清空大檔案,而且效率比較高。
1)建立空檔案
touch/data/blank.txt
2)用rsync清空檔案
rsync-a --delete-before --progress --stats /root/blank.txt /root/nohup.out
方法2、通過重定向到 Null 來清空檔案內容清空或者讓一個檔案成為空白的最簡單方式,是像下面那樣,通過 shell 重定向 null (不存在的事物)到該檔案:
# > access.log
方法3、使用符號或者命令(實際上就是用命令寫入覆蓋0內容),例如:
:符號
# : > access.log # true > access.log
命令寫入
# cat /dev/null > access.log
# cp /dev/null access.log
# dd if=/dev/null of=access.log
# echo "" > access.log 或者 # echo > access.log
# echo -n "" > access.log
# truncate -s 0 access.log
上面這兩種方法可以成功的刪除海量檔案,速度也很快。但還有一種更好的方法,比如要刪除上面提到的clientmqueue目錄,裡面全部是一個一個的郵件,用下面的方法:
service sendmail stop
cd /var/spool
mv clientmqueue clientmqueue-todelete
mkdir clientmqueue
chown --reference=clientmqueue-todelete clientmqueue
chmod --reference=clientmqueue-todelete clientmqueue
service sendmail start
rm -rf clientmqueue-todelete
上面的方法是將目錄重新命名,然後使用了 --reference 引用引數來重建目錄,然後刪除重新命名的目錄。直接刪除目錄的方法速度是十分的快。也可以留著備份不刪。更安全。
三、思考為什麼這些工具/命令能夠做到快速刪除(原理)
3、為什麼rsync能夠快速刪除大檔案?
1)rm命令大量呼叫了lstat64和unlink,可以推測刪除每個檔案前都從檔案系統中做過一次lstat操作。過程:正式刪除工作的第一階段,需要通過getdirentries64呼叫,分批讀取目錄(每次大約為4K),在記憶體中建立rm的檔案列表;第二階段,lstat64確定所有檔案的狀態;第三階段,通過unlink執行實際刪除。這三個階段都有比較多的系統呼叫和檔案系統操作。
2)rsync所做的系統呼叫很少:沒有針對單個檔案做lstat和unlink操作。命令執行前期,rsync開啟了一片共享記憶體,通過mmap方式載入目錄資訊。只做目錄同步,不需要針對單個檔案做unlink。
另外,在其他人的評測裡,rm的上下文切換比較多,會造成System CPU佔用較多——對於檔案系統的操作,簡單增加併發數並不總能提升操作速度。
總結:
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流
頻繁做減法不如直接從頭來過
把檔案系統的目錄與書籍的目錄做類比,rm刪除內容時,將目錄的每一個條目逐個刪除(unlink),需要迴圈重複操作很多次;rsync刪除內容時,建立好新的空目錄,替換掉老目錄,基本沒開銷。
【參考資料】Linux 下清空或刪除大檔案/大量檔案的幾種方法_linux 清空資料夾 https://blog.csdn.net/sd4493091/article/details/80414053