要找出 VPS 空間被誰佔用,我們需要從根目錄開始層層往下追蹤。你的硬碟總共 25G,目前已使用 17G,這對許多純文字服務的 VPS 來說確實偏高。
找出佔用空間的目錄
首先使用 du 指令來查看根目錄下各個資料夾的大小。這行指令會列出總量並由大到小排序,讓我們一眼看出兇手在哪:
Bash
sudo du -h --max-depth=1 / 2>/dev/null | sort -hr
通常佔用空間的常見原因有以下幾種:
系統日誌與快取
很多時候是日誌檔(Logs)累積太久沒有清理。你可以檢查 /var/log 資料夾。如果發現 journal 佔用太多,可以用這條指令限制日誌大小:
Bash
sudo journalctl --vacuum-size=500M
另外,如果你使用 Ubuntu 或 Debian,套件管理器的快取也可能堆積在 /var/cache/apt/archives。執行以下指令可以清除:
Bash
sudo apt-get clean
Docker 容器與鏡像
如果你有安裝 Docker,過期的鏡像(Images)和停止的容器(Containers)非常佔空間。你可以透過這個指令直接清除所有沒在使用的 Docker 資源:
Bash
docker system prune -a
隱藏在刪除程序中的檔案
有一種情況是檔案已經刪除了,但空間沒釋放。這是因為某個程序還在讀取該檔案。你可以用這條指令找出這些「幽靈檔案」:
Bash
sudo lsof / | grep deleted
如果看到很大的檔案被列出,重啟該服務或是直接重新開機就能討回空間。
你想先從哪個目錄查起,或是需要我幫你分析特定目錄的內容嗎?
➜ ~ sudo du -h --max-depth=1 / 2>/dev/null | sort -hr
17G /
9.5G /var
6.0G /usr
713M /boot
216M /root
159M /home
6.9M /etc
976K /run
56K /tmp
16K /lost+found
4.0K /Users
4.0K /srv
4.0K /opt
4.0K /mnt
4.0K /media
0 /sys
0 /proc
0 /dev
從你的查詢結果來看,最大宗的佔用集中在 /var (9.5G) 和 /usr (6.0G)。
追蹤 /var 目錄
/var 通常存放的是會變動的資料。最常見的兇手是日誌檔、套件快取或資料庫。請執行以下指令來縮小範圍:
Bash
sudo du -h --max-depth=1 /var 2>/dev/null | sort -hr
如果 /var/log 很大,通常是系統日誌堆積;如果 /var/lib 很大,則可能是 Docker 容器或是資料庫(如 MySQL)的數據庫檔案。
追蹤 /usr 目錄
/usr 佔用了 6.0G,這主要是系統安裝的軟體和函式庫。雖然 6G 對於現代 Linux 來說還在合理範圍,但如果你的 VPS 只有跑簡單服務,這可能代表裝了太多沒用的套件。你可以檢查看看是哪個子目錄最胖:
Bash
sudo du -h --max-depth=1 /usr 2>/dev/null | sort -hr
關於 /boot 的提醒
雖然 /boot 只佔了 713M,但對於某些 VPS 預設的磁碟分割來說,這可能會造成更新時空間不足。這通常是舊版的 Linux 核心(Kernel)堆積造成的。
你可以先執行 /var 的查詢指令,把結果貼出來,我們直接針對大頭進行清理嗎?
➜ ~ sudo du -h --max-depth=1 /var 2>/dev/null | sort -hr
9.5G /var
9.3G /var/lib
140M /var/log
9.2M /var/cache
632K /var/backups
36K /var/tmp
32K /var/www
28K /var/crash
16K /var/spool
4.0K /var/opt
4.0K /var/mail
4.0K /var/local
兇手已經抓到了,就是 /var/lib 這個目錄,它佔用了高達 9.3G。
在 Linux 中,/var/lib 是用來存放應用程式運行時狀態資料的地方。最常佔用這個位置的通常是 Docker 或資料庫檔案。
繼續深入定位
請執行以下指令,看看 /var/lib 裡面到底是哪個程式佔用了空間:
Bash
sudo du -h --max-depth=1 /var/lib 2>/dev/null | sort -hr
常見的情況預測
- 如果是 /var/lib/docker:這代表 Docker 的鏡像檔(Images)、容器層或是卷軸(Volumes)堆積太多。你可以先用
docker system df確認 Docker 的空間使用狀況。 - 如果是 /var/lib/mysql 或 /var/lib/postgresql:這代表你的資料庫資料量很大,或者是日誌檔(如 binlog)沒清理。
- 如果是 /var/lib/snapd:代表你使用 Snap 安裝了許多套件,它會保留舊版本的檔案。
你可以跑一下上面的指令,把前幾名列出來看看嗎?
➜ ~ sudo du -h --max-depth=1 /var/lib 2>/dev/null | sort -hr
9.3G /var/lib
8.9G /var/lib/mysql
273M /var/lib/apt
91M /var/lib/mecab
52M /var/lib/dpkg
6.2M /var/lib/ubuntu-advantage
3.4M /var/lib/command-not-found
704K /var/lib/usbutils
556K /var/lib/systemd
316K /var/lib/fwupd
124K /var/lib/ucf
40K /var/lib/polkit-1
36K /var/lib/PackageKit
28K /var/lib/pam
24K /var/lib/nginx
20K /var/lib/update-notifier
16K /var/lib/grub
12K /var/lib/update-manager
8.0K /var/lib/vim
8.0K /var/lib/ubuntu-release-upgrader
8.0K /var/lib/sudo
8.0K /var/lib/logrotate
8.0K /var/lib/landscape
8.0K /var/lib/cloud
8.0K /var/lib/apport
4.0K /var/lib/usb_modeswitch
4.0K /var/lib/upower
4.0K /var/lib/unattended-upgrades
4.0K /var/lib/udisks2
4.0K /var/lib/tpm
4.0K /var/lib/python
4.0K /var/lib/private
4.0K /var/lib/plymouth
4.0K /var/lib/os-prober
4.0K /var/lib/mysql-upgrade
4.0K /var/lib/mysql-keyring
4.0K /var/lib/mysql-files
4.0K /var/lib/misc
4.0K /var/lib/man-db
4.0K /var/lib/git
4.0K /var/lib/fail2ban
4.0K /var/lib/dhcp
4.0K /var/lib/dbus
4.0K /var/lib/boltd
結果非常明顯,佔用空間的元兇是 /var/lib/mysql,它獨自佔用了 8.9G。這代表你的 MySQL 資料庫存放了大量的數據,或者是產生了過多的日誌檔案。
檢查 MySQL 內部佔用
通常資料庫變大有兩個原因:一個是你的資料表真的很肥,另一個是開啟了 Binary Log(二進位日誌),這會記錄所有對資料庫的更動,主要用於備援與同步,但非常吃空間。
你可以進到該目錄看看有哪些大檔案:
Bash
sudo ls -lh /var/lib/mysql | sort -k 5 -rh | head -n 10
常見的清理方向
如果看到很多檔名類似 binlog.0000X 的檔案,那可以透過以下方式清理:
- 登入 MySQL:
sudo mysql -u root -p - 執行指令清理過舊的日誌(例如保留最近 3 天):
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY; - 或者是直接限制日誌保留的天數,修改 /etc/mysql/my.cnf 裡面的
binlog_expire_logs_seconds設定。
檢查特定的資料庫
如果你想知道是哪個資料庫(Database)或資料表(Table)最胖,可以登入 MySQL 後執行這段 SQL:
SQL
SELECT table_schema AS "Database",
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size (MB)"
FROM information_schema.TABLES
GROUP BY table_schema;
這能幫你確認是哪個專案的資料量異常。
需要我幫你看看 ls -lh 的結果,來判斷是數據檔還是日誌檔造成的嗎?
➜ ~ sudo ls -lh /var/lib/mysql | sort -k 5 -rh | head -n 10
-rw-r----- 1 mysql mysql 101M Jan 9 19:40 binlog.000032
-rw-r----- 1 mysql mysql 101M Jan 9 12:41 binlog.000031
-rw-r----- 1 mysql mysql 101M Jan 9 06:00 binlog.000030
-rw-r----- 1 mysql mysql 101M Jan 8 20:21 binlog.000028
-rw-r----- 1 mysql mysql 101M Jan 8 13:01 binlog.000027
-rw-r----- 1 mysql mysql 101M Jan 8 06:27 binlog.000026
-rw-r----- 1 mysql mysql 101M Jan 7 19:42 binlog.000024
-rw-r----- 1 mysql mysql 101M Jan 7 12:41 binlog.000023
-rw-r----- 1 mysql mysql 101M Jan 7 06:00 binlog.000022
-rw-r----- 1 mysql mysql 101M Jan 6 20:21 binlog.000020
從結果來看,你的 MySQL 產生了大量的 binlog(二進位日誌)。雖然單個檔案只有 101M,但數量顯然非常驚人,這就是吃掉你 8.9G 空間的主要原因。
解決方案:清理 binlog
這些檔案記錄了資料庫的所有更動,如果你沒有做資料庫主從同步(Replication)的需求,可以安全地清理它們。
請先登入 MySQL:
Bash
sudo mysql -u root -p
進入後執行以下指令,只保留最近 1 天的日誌(這會立即釋放大量空間):
SQL
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 1 DAY;
如果你完全不需要這些日誌,也可以直接刪除所有舊日誌,只保留目前正在使用的一個:
SQL
RESET MASTER;
預防措施:限制日誌保留天數
為了避免之後空間又被塞滿,建議修改 MySQL 設定檔。請編輯 /etc/mysql/mysql.conf.d/mysqld.cnf(或是 /etc/mysql/my.cnf):
使用指令:
vi /etc/mysql/mysql.conf.d/mysqld.cnf
- 找到
binlog_expire_logs_seconds
或expire_logs_days(舊版)。 - 設定較短的過期時間。例如保留 3 天($3 \times 24 \times 3600 = 259200$ 秒):
binlog_expire_logs_seconds = 259200
(預設值是 2592000) - 儲存後重啟 MySQL:
sudo systemctl restart mysql
執行完 PURGE 或 RESET MASTER 後,你可以再次執行 df -h 看看,空間應該會釋放好幾個 G。需要我幫你確認目前的設定檔位置嗎?