磁盤滿了,爲啥du卻顯示還有很大空間?

今天有個實習生問了我一個詭異的問題,「線下一臺磁盤大小32G的開發機(虛擬機)打不出日誌」,把追查過程和你們分享一下。
畫外音:貴司開發機磁盤容量多大?web

先du一下,查看磁盤空間:tomcat

[shenjian@dev02 ~]# du -sch /
16G /架構

畫外音:彷佛還有空間。負載均衡

再試了一下df,發現結果不同:ide

[shenjian@dev02 ~]$ df -h
文件系統 容量 已用 可用 已用% 掛載點
/dev/sda2 33G 33G 33G 100% /
/dev/sda1 965M 30M 886M 4% /boot代理

畫外音:顯示32G都用完了。日誌

du:disk usage

經過搜索文件來計算每一個文件的大小而後累加獲得的值。server

df:disk free

經過文件系統來獲取空間大小的信息。blog

若是用戶刪除了一個正在運行的應用程序所打開的某個目錄下的文件:進程

  • du命令返回的值,顯示出減去了該文件後的總大小
  • df命令返回的值,則不顯示減去該文件後的大小(文件句柄還在被使用),直到該運行的應用程序關閉了這個打開的文件(纔會真正釋放空間)

常見的場景是,刪除了一個很大的正在寫入的tomcat的access日誌,du顯示的結果會把日誌大小減去,而df則仍會包含該日誌的大小(實際上tomcat仍引用了該文件的句柄)。

對咱們的啓示是,若是要刪除某個access日誌,不要粗暴的rm,而要溫柔的:

echo "" > access.log

畫外音:朋友們,有沒有rm過仍被引用的日誌?

如何發現被應用程序引用着「已刪除」文件呢?
lsof:list open files
使用lsof查看打開的文件。

lsof | grep deleted
磁盤滿了,爲啥du卻顯示還有很大空間?
結果顯示,一個個人logsvr程序(跑了幾個月了),和實習生寫的web-server程序(實習大做業)呈現deleted狀態,值得懷疑。
畫外音:請在手機上把圖放大。

最終定位出,是web-server程序中的一個:
while(pid=fork())
手誤寫成了:
while(pid==fork())
致使while內一直fork進程,直到將系統資源吃幹。而且該進程已經成了zombie進程,沒法kill掉,重啓開發虛擬機後,問題獲得解決。
畫外音:我去,多了一個等號,這個bug好真實。

一分鐘不長,但願你們有收穫:

  • du:disk usage
  • df:disk free
  • lsof:list open files
  • echo "" > access.log

磁盤滿了,爲啥du卻顯示還有很大空間?
架構師之路-分享可落地的技術文章

相關推薦:
《負載均衡,必需要知道的5件事》
《「反向代理層」毫不能替代「DNS輪詢」》

課後做業:while(pid=fork())在何時會用到?

相關文章
相關標籤/搜索