liunx刪除文件後磁盤未減小


一. 場景一:進程打開此文件

    當一個文件正在被一個進程使用時,用戶刪除此文件,文件只會從目錄結構中刪除,但並沒有從磁盤刪除。當使用這個文件的進程結束後,文件纔會真正的從磁盤刪除,釋放佔有的空間。

    我們發現剩餘磁盤空間比較少時,回去刪除一些大的臨時文件或者log文件,如果刪除之後會發現磁盤空間並未減少,那麼可以通過“lsof”命令去查看正在使用該文件的進程,然後再重啓該進程或者服務。

    【例子】

    現在發現磁盤空間的佔用了99%,剩餘空間只剩下522M。


[plain] view plaincopy

  1. SUSE11X64-001:/test # df -h  

  2. Filesystem                       Size  Used Avail Use% Mounted on  

  3. /dev/sda2                         29G   27G  522M  99% /  

  4. devtmpfs                         972M  116K  972M   1% /dev  

  5. tmpfs                            972M     0  972M   0% /dev/shm  


     找到一個文件"vmcore"佔用了接近900M空間,但這個文件不需要再使用了,於是採用“rm”命令刪除此文件,可是刪除後,發現磁盤空間並沒有真正的減少。


[plain] view plaincopy

  1. SUSE11X64-001:/test # rm vmcore   

  2. SUSE11X64-001:/test # df -h  

  3. Filesystem                       Size  Used Avail Use% Mounted on  

  4. /dev/sda2                         29G   27G  522M  99% /  

  5. devtmpfs                         972M  116K  972M   1% /dev  

  6. tmpfs                            972M     0  972M   0% /dev/shm  

  7. //10.204.16.2/home/splx/iceking  6.3T  1.6T  4.7T  25% /mnt/iceking  

    也就是說很有可能有其他進程正在使用這個文件,使用“lsof”命令去查看正在使用該文件的進程。

[plain] view plaincopy

  1. SUSE11X64-001:/test # lsof | grep vmcore  

  2. a.out      2610       root    3r      REG                8,2 941331144    1643779 /test/vmcore (deleted)  

    進程號爲2610(進程名爲"a.out")的進程,正在使用vmcore文件,也可以看到其後有“deleted”:其表示正在使用的文件被刪除,但並沒有真正從磁盤上移除。


    現在我們刪除這個進程,並查看磁盤空間此時佔用率降低爲95%,剩餘空間增加到1.4G。


[plain] view plaincopy

  1. SUSE11X64-001:/test # df -h  

  2. Filesystem                       Size  Used Avail Use% Mounted on  

  3. /dev/sda2                         29G   26G  1.4G  95% /  

  4. devtmpfs                         972M  116K  972M   1% /dev  

  5. tmpfs                            972M     0  972M   0% /dev/shm 



二. 場景二:內核模塊Bug


    在文件系統處理文件需要的信息都存放在索引節點(inode)中,如果在刪除文件的時候索引節點的引用計數不爲0(表示文件正在被使用),則不會在磁盤中真正的刪除文件,從而保證正在使用此文件的進程能夠正常的處理文件。

    首先我們一起來看一下內核中關於文件系統的一些關鍵數據結構的關聯,當一個進程打開一個文件後,便會在內核中創建一個file對象,這個對象主要描述了進程如何與文件進行交互。file對象中將指向一個dentry結構(目錄項),目錄項中描述了目錄項名稱,父目錄項信息,子目錄項信息等。而dentry中的d_inode所指向的inode節點中則包含了實際的文件存儲在磁盤上的信息。



   當多個進程打開同一個文件時,內核中變會創建相應的file對象,但是他們都公用同一個dentry,只不過每一次打開文件dentry的引用計數d_count加1。並且對於打開的同一個文件而言,inode也是唯一的,inode的引用計數i_count一般爲文件硬鏈接的數目。看過一些中文博客,說“同一個文件,每打開一次,則inode中引用計數i_count則加1”,這種說法通過我的驗證結果是錯誤的。實驗結果是:對於同一個文件,每打開一次,則inode中的引用計數不變,但相應的dentry引用計數加1.

    這次客戶在刪除文件後,磁盤空間沒有釋放,通過"lsof"命令也沒有找到正在佔用此文件的進程。於是再次懷疑這是由於產品的內核模塊早成的。後經分析得到:在上一篇博文《Linux Kernel模塊內存泄露查找 (2)》中解釋過由於在產品內核模塊中,對dentry引用,並使用完之後並沒有對其引用計數減1,從而造成內存泄露。在這種情況下,dentry不會被釋放,則inode也就一直被引用着,從而也導致了即使刪除文件,也不會從磁盤刪除。

    而且針對以上的問題和分析,如果不能及時給客戶修這個問題,那也只能讓其重新啓動OS,空閒的磁盤空間纔會釋放出來。


來自:

http://blog.csdn.net/cjf_iceking/article/details/37593963

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章