Linux 磁碟空間排查與清理標準作業流程 (SOP)

階段一:快速確認整體磁碟狀態 (Filesystem Check)

在進入目錄細查前,先確認是磁碟容量不足還是 Inode 耗盡:

Bash
# 1. 檢查各掛載點空間使用率 (以 GB/MB 顯示)
df -h

# 2. 檢查 Inode 使用率 (若使用率達 100% 即使空間充裕也無法寫入新檔)
df -i

階段二:逐層下鑽定位高佔用目錄 (Drill-Down 核心流程)

排查關鍵在於加上 -x(--one-file-system)參數,強制不跨越其他掛載點與虛擬檔案系統(自動跳過 /proc、/sys、/dev 及外部 NFS/掛載磁區),大幅提升速度並避免報錯。

步驟 1:掃描根目錄 (/) 最大的第一層目錄

Bash
sudo du -xh --max-depth=1 / 2>/dev/null | sort -hr | head -n 15
依結果判定主要元兇位於哪一個分支(通常為 /var、/home 或 /data)。

步驟 2:進入目標大目錄向下鑽取 (Drill-Down)

假設發現 /home 佔比最高,接續檢查 /home 內部使用者:

Bash
sudo du -xh --max-depth=1 /home 2>/dev/null | sort -hr | head -n 15

步驟 3:進入特定使用者目錄(自動涵蓋隱藏檔 Dotfiles)

假設發現 /home/gitlab-runner 或 /home/tomcat 偏大,直接指定路徑即可自動列出所有一般與隱藏資料夾(無需使用易爆掉的 glob 語法):

Bash
sudo du -xh --max-depth=1 /home/gitlab-runner 2>/dev/null | sort -hr | head -n 15

步驟 4:跨目錄直接找出 Top 10 超大單一檔案

若目錄層級過深,可直接搜尋該目錄樹下體積最大的前 10 個實體檔案:

Bash
sudo find /home/gitlab-runner -xdev -type f -exec du -h {} + 2>/dev/null | sort -hr | head -n 10
維護人員捷徑(可加入 ~/.bashrc):

Bash
duck() { sudo du -xh --max-depth=1 "${1:-.}" 2>/dev/null | sort -hr | head -n 15; }
使用方式:duck / → duck /home → duck /home/tomcat

階段三:高佔用目標清理標準語法

1. 套件依賴與建置快取 (NPM / Package Cache)

Bash
# NPM 快取:以原帳號或 root 清理
npm cache clean --force
# 或實體刪除快取目錄
rm -rf ~/.npm/_cacache/*
sudo rm -rf /home/gitlab-runner/.npm/_cacache/*

# Yarn / Pnpm 快取
yarn cache clean
pnpm store prune

2. CI/CD 與容器環境 (GitLab Runner / Docker)

Bash
# GitLab Runner 專案建置與暫存目錄
rm -rf /home/gitlab-runner/cache/*
rm -rf /home/gitlab-runner/builds/*

# Docker 容器/映像檔清理
docker system prune -f

# Docker Buildx 建置快取清理
docker builder prune -a -f

3. 服務日誌安全清理 (Logs Truncate)

防踩坑準則:運行中的服務日誌切勿直接 rm。若行程未釋放 File Descriptor,磁碟空間將不會釋放。應採用 truncate 或重導向清空。

Bash
# PM2 日誌清理
pm2 flush

# Nginx / Tomcat / App 日誌安全截斷為 0-byte
truncate -s 0 /path/to/catalina.out
# 或使用 shell 內建清空語法
: > /path/to/access.log

# Systemd Journal 系統日誌清理 (保留最近 7 天或限額 500MB)
journalctl --vacuum-time=7d
journalctl --vacuum-size=500M

4. 系統套件庫暫存 (OS Package Cache)

Bash
# Ubuntu / Debian
sudo apt-get clean
sudo apt-get autoremove -y

# RHEL / CentOS / Rocky Linux
sudo dnf clean all || sudo yum clean all

5. 腳本/測試誤觸留下的 0-Byte 異常檔案

Bash
# 清理 curl/wget 遺漏引號造成的 HTTP Header 殘留檔案
rm -f ./Accept: ./GET ./Host: ./User-Agent: ./--header

階段四:刪檔後空間未釋放排查 (Deleted Handle)

若執行 rm 刪除超大日誌檔後,df -h 空間依然居高不下,代表該檔案仍被背景 Process 開啟著。
Bash
# 1. 查詢處於 deleted 狀態但仍被 process 佔用的檔案
sudo lsof +L1
# 或
sudo lsof | grep '(deleted)'

# 2. 處置方式:
# 方案 A:重啟持有該檔案的行程/服務 (最推薦)
sudo systemctl restart <service_name>

# 方案 B:無法重啟時,透過 /proc 直接釋放 (假設 PID=12345, FD=3)
: > /proc/12345/fd/3

階段五:驗證

Bash
# 1. 確認分割區可用容量
df -h

# 2. 驗證特定目錄剩餘大小
du -sh /home/gitlab-runner
# 再次檢視掛載點容量是否下降
df -h

# 驗證特定目錄清理後的容量
du -sh /path/to/target

修訂版本 #3
由 treeman 建立於 2026-09-30 14:22:40 CST
由 treeman 更新於 2026-09-30 14:26:50 CST