天天看點

linux删除檔案後空間未釋放

現象:删除log後df看空間未釋放

解決方案:1.rm删除檔案後,用lsof | grep XXX 查找使用該檔案的程序,kill程序即可立即釋放空間。

                  2.更好的方法是使用echo " ">file指令線上清空該檔案。

具體原因分析和具體指令使用請詳細閱讀如下内容:

複現現象:1.寫一個python程式,從public.log不停的複制内容寫檔案abc.txt

linux删除檔案後空間未釋放

                 2. 運作程式後,看目前路徑下檔案

linux删除檔案後空間未釋放

                3,檢視空間和df占用,删除正在被寫的檔案abc.txt,再次檢視空間占用

linux删除檔案後空間未釋放

               可以看到删除了檔案,空間并沒有釋放,反而還在增加。

               4.檢視是什麼程序占用了該檔案,有兩個python程序占用了該檔案,後面的(deleted)表示該檔案是已删除的

linux删除檔案後空間未釋放

             5.殺掉程序後,空間立即釋放

linux删除檔案後空間未釋放

更好的解決辦法:

        上面複現的過程已經有最基礎的解決方案,就是找到占用檔案的程序,殺程序,删檔案,此解決方案太過粗暴,有以下理由

              理由一:伺服器中某些打log的程序是不能随意删除。

              理由二:某個檔案可能被多個程序占用,或者幾十個程序占用,想釋放空間就得殺掉是以程序。

        解決方案二:采用将該檔案置空的辦法,執行echo " " >abc.txt

             該方案可以線上清空log,但親測執行時間過長,可能是我每秒寫600m的程序太特殊導緻。需要權衡,若可以等或者程序不能停,就采用此方法,否則就采用kill程序的方法。

linux删除檔案後空間未釋放

原因探索:        

Linux下檔案的存儲機制和存儲結構:

            一個檔案在檔案系統中的存放分為兩個部分:資料部分和指針部分,指針位于檔案系統的meta-data中,資料被删除後,這個指針就從meta-data中清除了,而資料部分存儲在磁盤中,資料對應的指針從meta-data中清除後,檔案資料部分占用的空間就可以被覆寫并寫入新的内容,之是以出現删除abc.txt檔案後,空間還沒釋放,就是因為python程序還在一直向這個檔案寫入内容,導緻雖然删除了abc.txt檔案,但檔案對應的指針部分由于程序鎖定,并未從meta-data中清除,而由于指針并未被删除,那麼系統核心就認為檔案并未被删除,是以通過df指令查詢空間并未釋放也就不足為奇了。          

          在檔案系統處理檔案需要的資訊都存放在索引節點(inode)中,如果在删除檔案的時候索引節點的引用計數不為0(表示檔案正在被使用),則不會在磁盤中真正的删除檔案,進而保證正在使用此檔案的程序能夠正常的處理檔案。

          首先我們一起來看一下核心中關于檔案系統的一些關鍵資料結構的關聯,當一個程序打開一個檔案後,便會在核心中建立一個file對象,這個對象主要描述了程序如何與檔案進行互動。file對象中将指向一個dentry結構(目錄項),目錄項中描述了目錄項名稱,父目錄項資訊,子目錄項資訊等。而dentry中的d_inode所指向的inode節點中則包含了實際的檔案存儲在磁盤上的資訊。

linux删除檔案後空間未釋放

           當多個程序打開同一個檔案時,核心中變會建立相應的file對象,但是他們都公用同一個dentry,隻不過每一次打開檔案dentry的引用計數d_count加1。并且對于打開的同一個檔案而言,inode也是唯一的,inode的引用計數i_count一般為檔案硬連結的數目。

驗證上述說明:

1.背景往abc.txt寫的腳本沒停,繼續寫,将檔案重命名為abc.log

linux删除檔案後空間未釋放

2.删除重命名後的檔案

linux删除檔案後空間未釋放

3.删除後用df指令發現所占空間沒有減小,檢視占用程序發現abc.txt沒有程序占用,重命名後的abc.log有程序占用,說明重命名該檔案,但inode并沒有改變,linux通過inode來查找對應檔案,是以繼續往重命名後的檔案寫入。

         Linux系統内部不使用檔案名,而使用inode号碼來識别檔案。對于系統來說,檔案名隻是inode号碼便于識别的别稱或者綽号。表面上,使用者通過檔案名,打開檔案。實際上,系統内部這個過程分成三步:首先,系統找到這個檔案名對應的inode号碼;其次,通過inode号碼,擷取inode資訊;最後,根據inode資訊,找到檔案資料所在的block,讀出資料。

linux删除檔案後空間未釋放

繼續閱讀