背景
一臺測試服務器,/data磁盤大小為300G,時不時就滿了,通過df命令查看300G基本全用了,use 100%。但是進到/data目錄中通過du 命令查看,也就用了20個G左右,怎么都對不上。如何清理都沒有釋放太多空間。查看如下所示:
df -lh
du -lh *
排查
出現以上問題,即df -lh 查看和du -lh 查看磁盤大小不同,排查思路:
- 檢查是否掛載點出現問題,即沒找到相應的掛載點或者是掛載點覆蓋了原來的磁盤目錄。
# mount 命令檢查掛載點
mount |grep '/data'
沒看出來啥問題,這個命令執行完后,和df -lh顯示的目錄對應的文件系統是一致的,好像也沒啥錯啊。
2. 是否是有些文件刪除后,沒有釋放導致的呢?先檢查一下哪些文件被標記為已刪除的文件
lsof +L1|grep '/data'|grep -i deleted
上述命令中含義如下所示:
- lsof 是查找,
- +L1:列出所有連接計算小于1的文件(已被刪除的文件)
- grep ‘/data’: 只顯示/data 目錄下的文件
- grep -i ‘deleted’:過濾出狀態為deleted的文件
執行此命令后,輸出會包含多列,其中我們需要關注的是“PID”列(進程ID)和“FD”列(文件描述符),顯示如下所示:
還真有很多被標記了已刪除的文件,到底有沒有完全刪除釋放空間啊?不知道,如何撤底刪除呢?(好比windows下我們刪除了文件,進了回收站,實際還是會占用C盤資源一樣,我們需要清空回收站)
“清空回收站”需要以下命令:
truncate -s 0 /proc/[PID]/fd/[FD_NUM] # 通過lsof獲取FD_NUM
如何查找PID、FD_NUM呢,需要了解一下lsof那一步中顯示結果各列的含義了。以下補充了表頭信息,我們只需找到對應的PID 和FD_NUM即可.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME STATUS
java 978732 appuser 1w REG 253,4 303252014991 0 269777363 /data/js/WARN_CENTER/warn_center.log (deleted)
java 978732 appuser 2w REG 253,4 303252014991 0 269777363 /data/js/WARN_CENTER/warn_center.log (deleted)
java 978732 appuser 4r REG 253,4 0 0 269664611 /data/js/WARN_CENTER/warn_center.jar (deleted)
java 978732 appuser 10r REG 253,4 0 0 269664611 /data/js/WARN_CENTER/warn_center.jar (deleted)
由此可見,PID為第二列對應的978732,FD_NUM對應的是第四列FD且只取數字即可:1W中的1;2W中的2即可,而其后面的字母代表文件模式,如w代表可寫入;
下面我們執行"清空回收站"的命令吧:
truncate -s 0 /proc/978732/fd/1
truncate -s 0 /proc/978732/fd/2
操作完再次df -lh檢查,磁盤已釋放了,問題圓滿解決
總結
df 磁盤占用100%,du占用很少時,兩個命令對應不上大小時,可以試著清空“回收站”(已被刪除的文件,未釋放資源)
- 查看刪除狀態的文件有哪些,并找到相應的PID和FN_NUM
lsof +L1|grep '/data'|grep -i deleted
- 通過truncate命令清除掉所有刪除文件占用的資源
#PID參考上述命令結果中的第二列;FUN_NUM參考第四列并只取數字truncate -s 0 /proc/[PID]/fd/[FUN_NUM]
以上就是解決問題的問鍵了,但是還有一個問題,為啥rm -rf刪除文件后,沒有釋放資源呢,原因就是進程并沒有重啟,如果進程重啟后也可以釋放,如沒重啟,空間資源就未釋放了,那我們是不是也可以通過程啟進程的方法替換truncate呢,答案是肯定的。當然可以。
除此,一般清理磁工作,可以通過du命令查看當前文件夾以子文件夾占用空間最大的文件,并指定排序后取前N條,參考以下命令
#du -ah --max-depth=1 |sort -rh|head -n 20
du -ah |sort -rh|head -n 20
du 和df 都是Linux下磁盤空間管理的兩個核心命令,有啥區別啊?
概述一下兩命令使用場景:df查看整個磁盤或分區的使用情況,而du分析特定目錄或文件的空間占用。df 看大盤,du 查細節
兩個命令后面常用到的參數說明:
-a: (all): 顯示所有的文件和目錄占用空間(默認僅顯示目錄)
-h(human-readable) 不加 ?h 時輸出單位為字節,可讀性差。加了h是用人類能看懂的方式整式,以 K/M/G/T 等易讀單位自動轉換字節值(例如 1.2G 代替 1234567890)
- 日常檢查用 du?sh(只顯示目錄總和)
- 深度分析用 du?ah??max?depth=N(控制遞歸深度)