Linux 硬碟空間已滿怎麼辦?VPS 找出並釋放磁碟空間教學

10 分鐘閱讀 5 次閱讀 0
本文目錄

「No space left on device」幾乎會讓伺服器上所有東西出問題:資料庫無法寫入、網站回傳錯誤、套件更新失敗,有時甚至無法正常登入。本文一步步說明如何排除 Linux 硬碟空間已滿:先確認是區塊還是 inode 用完,再用 du 與 ncdu 找出佔用空間的元兇,最後從 systemd 日誌、apt/dnf 快取、Docker、過大的日誌檔,以及已刪除但仍被開啟的檔案中釋放磁碟空間。指令涵蓋 Debian、Ubuntu、CentOS 7 與 Rocky Linux / AlmaLinux 8、9。

步驟 1:用 df -hT 與 df -i 檢查磁碟使用量

先找出是哪個檔案系統滿了。即使還有好幾 GB 空間,只要 inode 用完,磁碟同樣會顯示「已滿」——應用程式產生數百萬個小檔案時就會發生。

df -hT          # space per file system, with type
df -i           # inodes: IUse% at 100% also means "No space left on device"

若 Use% 達到 100%,請繼續步驟 2;若只有 IUse% 偏高,請直接跳到步驟 9。

步驟 2:用 du 找出大型目錄與檔案

du 會統計每個目錄的大小。-x 參數只計算同一個檔案系統,避免掛載的硬碟與虛擬檔案系統干擾結果。請一層一層往下追查。

# Largest top-level directories on the root file system
du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -n 15
# Drill down into the biggest one, for example /var
du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -n 15

# Single files larger than 200 MB
find / -xdev -type f -size +200M -exec ls -lh {} + 2>/dev/null | sort -k5 -h

步驟 3:用 ncdu 互動式瀏覽磁碟使用量

ncdu 只掃描一次,就能用方向鍵瀏覽整個目錄樹,比反覆執行 du 快得多。若磁碟完全滿到無法安裝,請先用步驟 4 或步驟 5 釋放一點空間。

# Debian / Ubuntu
apt install -y ncdu
# Rocky Linux / AlmaLinux / CentOS (from EPEL)
dnf install -y epel-release && dnf install -y ncdu

ncdu -x /       # arrows to browse, d = delete, q = quit

步驟 4:縮減 systemd 日誌(journalctl --vacuum)

啟用持久化日誌的系統,/var/log/journal 可能長到好幾 GB。vacuum 會安全地刪除最舊的封存日誌,設定大小上限則能避免問題再次發生。

journalctl --disk-usage
journalctl --vacuum-size=200M      # or: journalctl --vacuum-time=14d

# Cap the journal permanently
mkdir -p /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/size.conf <<'EOF'
[Journal]
SystemMaxUse=200M
EOF
systemctl restart systemd-journald

步驟 5:清理 apt / dnf 快取與舊核心

已下載的套件與舊核心是最快見效的清理目標,在小容量雲端硬碟上尤其明顯。

# Debian / Ubuntu
apt clean
apt autoremove --purge

# Rocky Linux / AlmaLinux 8, 9
dnf clean all
dnf remove $(dnf repoquery --installonly --latest-limit=-2 -q)   # keep 2 newest kernels

# CentOS 7
yum clean all
yum install -y yum-utils && package-cleanup --oldkernels --count=2

步驟 6:安全處理大型日誌檔

/var/log 或網站目錄中的應用程式日誌,是硬碟被塞滿的常見原因。不要直接 rm 仍在被服務寫入的日誌,空間並不會釋放(見步驟 8)。請改用 truncate 清空,再修正日誌輪替設定。

# Log files larger than 100 MB
find /var/log -type f -size +100M -exec ls -lh {} +

# Empty a live log WITHOUT deleting it (the service keeps writing)
truncate -s 0 /var/log/nginx/access.log

# Remove compressed rotated logs older than 14 days
find /var/log -type f -name '*.gz' -mtime +14 -delete

# Dry-run logrotate to see why a log is not rotating
logrotate -d /etc/logrotate.conf

步驟 7:清理 Docker 佔用的空間(docker system prune)

舊映像檔、已停止的容器與建置快取會在 /var/lib/docker 快速累積。先檢查,再清理。

docker system df                   # what Docker is using
docker system prune                 # stopped containers, unused networks,
                                    # dangling images and build cache
docker system prune -a              # also ALL images not used by a container

# Container logs live here and can grow without limit
du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail
除非非常確定,否則不要加上 --volumes:它會永久刪除未使用的 Docker volume,裡面常常存放著資料庫資料。

為了避免容器日誌再次塞滿硬碟,請設定大小上限:

# /etc/docker/daemon.json - limit future container logs
{
  "log-driver": "json-file",
  "log-opts": { "max-size": "50m", "max-file": "3" }
}
# then: systemctl restart docker  (applies to newly created containers)

步驟 8:用 lsof +L1 找出已刪除但仍開啟的檔案

當 df 顯示硬碟已滿,du 卻找不到空間去哪裡時,通常是某個程式仍開著一個已被刪除的檔案。要等該程式關閉檔案,空間才會釋放。

# Debian / Ubuntu: apt install -y lsof   |   Rocky / AlmaLinux: dnf install -y lsof
lsof +L1
# COMMAND  PID  ...  SIZE/OFF  NLINK  NAME
# php-fpm  1234 ...  4.2G      0      /var/log/app/debug.log (deleted)

# Fix 1: restart the service holding the file
systemctl restart php-fpm
# Fix 2: truncate it through /proc (PID 1234, file descriptor 7 from "ls -l /proc/1234/fd")
: > /proc/1234/fd/7

步驟 9:處理 inode 用盡造成的「No space left」

當 df -i 顯示 100% 時,請找出含有大量小檔案的目錄,例如 PHP session 資料夾、郵件佇列、快取目錄或暫存上傳檔。

# Directories that contain the most files
find / -xdev -type f 2>/dev/null | cut -d/ -f2-4 | sort | uniq -c | sort -n | tail -n 10

清理對應的目錄,並設定應用程式自動清除舊檔案。

常見問題

為什麼 df 與 du 顯示的數字不同?

多半是已刪除但仍被開啟的檔案(步驟 8)。此外,被掛載點遮住的檔案,以及 ext4 為 root 保留的空間(預設 5%)也會造成差異。

可以把 /var/log 裡的東西全部刪掉嗎?

不建議。請刪除舊的 .gz 輪替檔、清空過大的使用中日誌,但保留目錄結構;部分服務在日誌目錄不存在時會無法啟動。

硬碟一直被塞滿,可以加大空間嗎?

請先依上述步驟找出根本原因。若資料確實需要更多空間,JUSTG 雲端伺服器可加購 SSD 容量,請在客戶中心查看升級選項或提交工單。

如 Linux 伺服器的硬碟空間問題仍未解決,請至 https://www.justg.com/submitticket.php 提交工單,JUSTG 技術支援團隊會協助您處理。

这篇文章有帮助吗?