磁盘满了,为啥du却显示还有很大空间?
今天有個實習生問了我一個詭異的問題,“線下一臺磁盤大小32G的開發機(虛擬機)打不出日志”,把追查過程和大家分享一下。
畫外音:貴司開發機磁盤容量多大?
?
先du一下,查看磁盤空間:
[shenjian@dev02?~]# du -sch /
16G ? ? /
畫外音:似乎還有空間。
?
再試了一下df,發現結果不一樣:
[shenjian@dev02 ~]$ df -h
文件系統 ? ? ?? 容量 ?已用 可用 已用% ?掛載點
/dev/sda2 ? ?? 33G ? 33G ? 33G ?100% /
/dev/sda1 ? ?? 965M ? 30M ?886M ? 4% /boot
畫外音:顯示32G都用完了。
?
du:disk usage
通過搜索文件來計算每個文件的大小然后累加得到的值。
?
df:disk free
通過文件系統來獲取空間大小的信息。
?
如果用戶刪除了一個正在運行的應用程序所打開的某個目錄下的文件:
-
du命令返回的值,顯示出減去了該文件后的總大小
-
df命令返回的值,則不顯示減去該文件后的大小(文件句柄還在被使用),直到該運行的應用程序關閉了這個打開的文件(才會真正釋放空間)
常見的場景是,刪除了一個很大的正在寫入的tomcat的access日志,du顯示的結果會把日志大小減去,而df則仍會包含該日志的大小(實際上tomcat仍引用了該文件的句柄)。
?
對我們的啟示是,如果要刪除某個access日志,不要粗暴的rm,而要溫柔的:
echo "" > access.log
畫外音:朋友們,有沒有rm過仍被引用的日志?
?
如何發現被應用程序引用著“已刪除”文件呢?
lsof:list open files
使用lsof查看打開的文件。
?
lsof | grep deleted
結果顯示,一個我的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却显示还有很大空间?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 中关于 null 对象的容错处
- 下一篇: MySQL 中一个双引号的错位引发的血案