【系統維運】

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