Linux 刪了日誌,磁碟為什麼還是滿的?看懂開啟中的檔案 / Why Deleting a Linux Log May Not Free Disk Space
刪掉的是什麼? / What was actually removed?
假設你在 Linux 伺服器刪掉一個很大的舊日誌,目錄裡已經找不到它,磁碟用量卻幾乎沒變。先別急著再刪一輪:檔名消失,不一定代表資料已經釋放。本文聚焦一種常見原因,也就是仍有程序開著那個檔案,不把所有空間問題都歸到同一個答案。
Imagine deleting a large old log on a Linux server. It disappears from the directory, yet disk usage barely changes. Resist deleting more files: a missing name does not necessarily mean the data has been released. This article focuses on one common cause—a process still has the file open—not a universal explanation for every space problem.
依 Linux 系統呼叫手冊,unlink 移除的是檔案系統中的一個名稱。只有當它是最後一個硬連結,而且沒有程序開著檔案,佔用的空間才會供重新使用。硬連結可以理解成同一份檔案的另一個名字;刪掉其中一個名字,並不是刪掉其他名字。[1]
According to the Linux system-call manual, unlink removes a name from the filesystem. The space becomes reusable when that was the last hard link and no process has the file open. A hard link is another name for the same file; removing one name does not remove the others. [1]
程序開啟檔案後,會取得檔案描述符,也就是用來操作已開啟檔案的編號。即使最後一個名字被移除,只要仍有描述符指向它,檔案就會繼續存在,直到最後一個相關描述符關閉。因此,目錄中的名稱與程序手上的開啟狀態,要分成兩條線來看。[1][2]
Opening a file gives a process a file descriptor: a number used to operate on an open file. Even after its last name is removed, the file remains while a descriptor still refers to it, until the last such descriptor is closed. Directory names and the process’s open-file state therefore need to be considered separately. [1][2]
程序手上還握著什麼? / What does the process still hold?
這也解釋了為什麼日誌從目錄消失,服務卻可能繼續向原本開著的檔案寫入。重新建立同名檔案,不會自動讓既有描述符改指向新檔。這是從上述機制推得的情境,不是本文在正式伺服器做過的實測,也不是建議你直接拿正在使用的日誌試刪。
This explains why a service may keep writing to the file it already opened after the log disappears from the directory. Creating another file with the same name does not automatically redirect its existing descriptor. This scenario follows from the mechanism above; it is not a production-server test performed for this article, nor a recommendation to delete an active log.
先觀察,再安排處理 / Observe before intervening
排查時,先在有 GNU 工具的 Linux 執行 df -h /var/log,確認日誌所在檔案系統的空間,而不是只看某個檔名。這是唯讀查詢;若你的日誌放在別處,請換成實際存在的目錄。df 回報的是檔案系統用量,不能單靠這張表判定是哪個程序佔住檔案。[3]
On Linux with GNU tools, start with df -h /var/log to inspect space on the filesystem containing the logs rather than a particular filename. This is read-only; substitute an existing directory if your logs are elsewhere. Since df reports filesystem usage, its table alone cannot identify the process holding a file open. [3]
接著從服務管理資訊確認程序編號,再查看 /proc/程序編號/fd 裡的連結。這個目錄依描述符編號列出程序開啟的檔案,可幫助比對目標;存取受權限限制,看不到不等於沒有開啟。下方命令須把 PID 換成實際編號,本文提供觀察方法,不宣稱已在你的系統執行。[2]
Next, obtain the process ID from your service-management information and inspect the links under /proc/process-ID/fd. Its entries are named by descriptor number and help you match open files to their targets. Access is permission-controlled, so inability to inspect it does not prove that nothing is open. Replace PID below with the actual number; these are observation instructions, not commands claimed to have run on your system. [2]
# Linux;將 PID 換成實際程序編號 / Replace PID with the actual process ID
df -h /var/log
ls -l /proc/PID/fd若確認服務仍握著已刪除的日誌,應依服務文件安排重新開啟日誌或安全重啟,先評估中斷影響,不直接強殺程序。回到那個沒有下降的用量數字,你現在多了一個判斷方向:不只找「檔案還在哪」,也要找「誰還開著它」,再決定下一步。
If a service is confirmed to hold the deleted log open, follow its documentation to arrange log reopening or a safe restart, assessing disruption first instead of forcibly killing it. Returning to the unchanged usage figure, you now have another diagnostic question: not only “Where is the file?” but also “Who still has it open?” Let that evidence guide the next step.

留言
張貼留言