深入解析:用 lsof 揪出“幽靈文件”釋放磁盤空間
日常運維中,你是否遇到過這樣的情況:明明已經刪除了大文件,但磁盤空間卻遲遲未釋放?du 顯示沒問題,df 卻提示磁盤快滿?這背后可能隱藏著一種“幽靈文件”現象。本文將帶你深入了解問題根源,并借助 lsof 工具快速定位并解決這類疑難問題。
什么是“幽靈文件”?
“幽靈文件”(又叫 deleted but open files)是指已經被從文件系統中刪除,但依然被某些進程打開著的文件。它們不再出現在目錄結構中,但因為被進程持有,它們的空間不會被釋放。
?? 舉個例子:你運行了一個程序,它在寫一個日志文件 audit.log。某天你為了節省空間直接刪除了 audit.log,但這個程序并沒有關閉文件句柄,導致這部分空間仍然被占用。
[root@s-zb-dba02 mnt]# lsof +L1 | grep deleted
auditd 6134 root 4w REG 253,0155446270995536 /var/log/audit/audit.log (deleted)
.....
問題表現
使用 df -h 看到根目錄快滿:
[root@s-zb-dba02 mnt]# df -h
文件系統 容量 已用 可用 已用% 掛載點
devtmpfs 252G 0 252G 0% /dev
tmpfs 252G 771M 252G 1% /dev/shm
tmpfs 252G 14G 239G 6% /run
tmpfs 252G 0 252G 0% /sys/fs/cgroup
/dev/mapper/rhel-root 42G 41G 1.2G 98% /
....
而 du -sh /* 卻發現加起來沒這么多空間:
du-sh /*
8G /var
1G /home
...
總計加起來遠遠小于 42G
這就說明:有空間被“非文件系統中的文件”占用了,也就是“幽靈文件”!
lsof 是什么?
lsof(List Open Files)是 Linux 系統的核心診斷工具,它能列出所有進程打開的文件資源。在 Linux哲學中"一切皆文件"的背景下,lsof 可查看的不僅是常規文件,還包括:
- 網絡套接字(TCP/UDP)
- 管道(PIPE)和 FIFO
- 共享內存
- 設備文件
- 被刪除但仍被進程占用的文件
基礎用法速查:
# 查看指定進程打開的文件
$ lsof-p<PID>
# 查看指定用戶打開的文件
$ lsof-u<username>
# 查看指定目錄下被打開的文件
$ lsof +D /path/to/dir
# 查看指定文件系統的打開文件(推薦排查磁盤空間問題)
$ lsof +aL1 <mount-point>
關鍵參數解析:
- +a:AND條件組合
- +L1:僅顯示鏈接數小于1的文件(即被刪除的文件)
- +aL1:組合條件查找已刪除但被占用的文件
如何用 lsof 揪出“幽靈文件”?
你只需要一條命令,就能找到這些占用磁盤空間的“幽靈文件”:
lsof +L1 |grep deleted
示例輸出:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
auditd 6134 root 4w REG 253,0155446270995536 /var/log/audit/audit.log (deleted)
tuned 7696 root 3w REG 253,054912034451806 /var/log/tuned/tuned.log (deleted)
rsyslogd 7700 root 5w REG 253,0391297111920101454061 /var/log/messages-20250310 (deleted)
rsyslogd 7700 root 6w REG 253,0391297111920101454061 /var/log/messages-20250310 (deleted)
rsyslogd 7700 root 7w REG 253,0391297111920101454061 /var/log/messages-20250310 (deleted)
rsyslogd 7700 root 8w REG 253,0391297111920101454061 /var/log/messages-20250310 (deleted)
字段解釋:
- COMMAND:哪個進程
- PID:進程 ID
- FILE:文件類型(txt、mem、del等)
- SIZE:文件大小
- NAME:文件路徑(顯示 deleted)
如何解決?
(1) 方法一:重啟進程(推薦)
找到對應的 PID,使用如下命令結束它:
kill-91234
或者優雅重啟進程(推薦):
systemctl restart auditd
注意:重啟服務前請確保不影響業務運行!
(2) 方法二:使用 truncate 清空文件
若不能重啟,可以通過 proc 文件系統,清空該文件句柄:
truncate -s0 /proc/6134/fd/4
其中 6134 是 PID,4 是對應的文件描述符,可在 lsof 結果中找到。
預防措施
- 程序中使用日志輪轉(logrotate)+ 信號通知關閉舊句柄。
- 日志定期清理時,建議使用 truncate 而不是 rm。
- 定期巡檢系統中被刪除但仍然打開的文件:
lsof|grep deleted
小結
“幽靈文件”雖不常見,但一旦出現就很容易造成磁盤空間莫名減少。掌握 lsof,不僅能迅速定位問題,更能為你節省大量排查時間。
記住:刪除不等于釋放,進程還在引用,就還占空間!