"No space left on device" 從來不會在方便的時候出現。資料庫拒絕寫入,apt 升級到一半卡住,Docker 偏偏拒絕拉取您此刻最需要的那個映像。好訊息是:在小 VPS 上,罪魁禍首幾乎總是五樣東西之一,兩分鐘就能找到。
1. 情況有多糟?
df -h /
df -i /
第一行顯示已用空間。第二行顯示 inode——如果空間看起來還夠,inode 卻到了 100%,說明您有幾百萬個小檔案(工作階段檔案、郵件佇列、快取目錄)。問題不同,症狀相同。
2. 找出大塊頭
從頂層開始遍歷目錄樹,按大小排序:
du -xh / --max-depth=1 2>/dev/null | sort -h | tail -15
-x 只停留在一個檔案系統裡,不會鑽進 /proc。然後再深入最大的那個目錄。想互動式瀏覽的話,ncdu 要舒服得多:
apt install -y ncdu
ncdu -x /
方向鍵移動,d 刪除。用最後那個鍵時要小心。
3. 立竿見影的清理
這些指令在任何 Ubuntu 或 Debian 伺服器上都是安全的:
apt clean
apt autoremove --purge -y
journalctl --disk-usage
journalctl --vacuum-size=200M
apt autoremove 也會清掉舊核心。最讓人意外的是 systemd 的 journal——放任不管的話它能長到好幾 GB。想永久限制它,在 /etc/systemd/journald.conf 裡設定 SystemMaxUse=200M,再執行 systemctl restart systemd-journald。
4. Docker 殘留
如果您在用 Docker,先看這裡。舊映像和建置快取會隨著每次部署越堆越多:
docker system df
docker image prune -a
docker builder prune
docker image prune -a 會刪除沒有被任何執行中容器使用的映像。通常這正是您想要的,但下次部署時它們會被重新拉取。
危險的是 docker system prune -a --volumes。卷裡存著您的資料,而掛在已停止容器上的卷會被當作未使用。很多人就是這樣丟了資料庫。別從論壇答案裡直接貼上這條指令。
另一個隱形的空間殺手是容器記錄。在 /etc/docker/daemon.json 裡給它們設上限:
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}
之後重新啟動 Docker。這個限制只對之後建立的容器生效,所以要用 docker compose up -d --force-recreate 重建那些記錄寫得多的容器。
5. 記錄和被遺忘的檔案
在整個磁碟上查詢大檔案:
find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null
find /var/log -type f -size +100M -exec ls -lh {} + 2>/dev/null
常見的發現:/root 裡半年前的 backup.tar.gz、某人本想下載的資料庫轉儲、從來沒輪轉過的應用記錄。
對於服務還在寫入的記錄,別用 rm 刪——清空它:
truncate -s 0 /var/log/myapp/app.log
如果已經刪了一個而空間沒有回來,說明還有程式開著它:
lsof +L1
重新啟動列出來的那個服務,空間就會回來。
清理也不夠時
有時候資料就是實打實需要的——不斷增長的資料庫、使用者上傳的檔案、模型檔案。這時誠實的辦法就是加磁碟。升級方案會原地擴充磁碟並保留一切:Nano 有 15 GB,Micro 25 GB,Small 35 GB,Medium 45 GB。伺服器會重新啟動一次。詳情見方案文件。
還有一樣東西在悄悄佔空間:swap 檔案。如果您按我們的 swap 指南做過,那 1–2 GB 是特意留出來的。如果 Docker 是最大的消耗者,Docker 安裝指南和 Compose 棧指南講了怎麼控制映像數量。
能防住這一切的習慣:第一天就給 journal 和 Docker 記錄設上限。兩行設定,"磁碟已滿"基本就不會再發生。
評論
目前還沒有評論。歡迎成為第一位。