首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Linux 大文件刪除後磁盤空間未釋放?lsof 定位進程佔用與在線清空實戰

     編輯:Java 綜合教學

Linux 大文件刪除後磁盤空間未釋放?lsof 定位進程佔用與在線清空實戰

運維高頻場景:rm 刪除超大日志文件,df -h 顯示磁盤佔用毫無變化。根因在於 文件被進程持有打開,目錄項 (dentry) 已刪除,但 inode 連接數 > 0,數據塊不回收。本文提供標準排查與零停機釋放方案。

一、現象復現與原理

  • 文件系統存儲分兩部分:目錄項 (文件名→inode) 與 數據塊 (inode→磁盤扇區)
  • rm 僅刪除目錄項,若進程持有文件描述符 (fd),inode 連接計數不歸零,數據塊標記為「使用中」
  • df 統計數據塊使用量,du 遍歷目錄項統計,故 df > du

二、標準排查流程

# 1. 定位大文件 (示例:/tmp/access_log 66G)
du -s /tmp/* | sort -nr | head -3

# 2. 刪除文件
rm /tmp/access_log

# 3. 發現 df 未釋放,查找持有進程
lsof | grep deleted
# 輸出示例:
# httpd   1234 root  4u   REG  253,0  70G  12 /tmp/access_log (deleted)

關鍵列:PID (進程 ID)、FD (文件描述符)、SIZE (當前大小)、(deleted) 標記。

三、三種釋放方案對比

方案操作優點缺點/風險
殺掉進程kill -9 1234徹底釋放業務中斷、數據丟失風險
重啟服務/機器systemctl restart httpd安全釋放停機時間長、影響面大
在線清空 (推薦)> /tmp/access_log 或 echo "" > /tmp/access_log零停機、即時釋放、進程繼續寫入需確保進程以追加模式寫入

四、在線清空原理與最佳實踐

# 方法 1:重定向清空 (最常用)
: > /tmp/access_log
# 或
echo "" > /tmp/access_log

# 方法 2:truncate 系統調用 (需 root)
truncate -s 0 /tmp/access_log
  • Shell 重定向 > 以 O_TRUNC 打開文件,內核將文件大小置 0,釋放數據塊,文件描述符保持有效
  • 進程下一次 write() 從偏移量 0 繼續寫入,邏輯無感
  • 適用於 Nginx/Apache/Tomcat/Jetty 等標準日志輸出進程

五、預防機制

  1. 配置 logrotate 定期切割壓縮,copytruncate 模式無需重啟
  2. 應用層接入日志框架 (Logback/Log4j2) 內建滾動策略,避免直接寫大文件
  3. 監控告警:df -h 使用率 > 80% 觸發巡檢
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved