最近維護一台 Ubuntu Server 時,遇到一個非常詭異的狀況:
- PM2 的 process 全部消失
- Apache 沒有回應
- MySQL 無法啟動
一開始以為是 記憶體不足導致服務 crash,結果一路排查後才發現真正原因其實很單純:
硬碟滿了…..
這篇記錄完整的排查過程。
系統環境
- Ubuntu Server
- Apache2
- MySQL
- PM2
- Docker
第一個症狀:PM2 process 全部消失
登入 server 後,第一件事先檢查 PM2:
pm2 list
結果發現,所有 PM2 process 都消失了。正常情況下,PM2 的 process 不太可能全部消失。第一個直覺是:最近有用 Docker,可能是記憶體不足導致 PM2 被系統 kill。
正當這樣想的時候…
第二個症狀:Apache 也沒有回應
接著測試 Apache
systemctl status apache2
Apache 卻顯示正常運作
也確實有在 listen 80 port:
ss -tlnp | grep :80
但奇怪的是 curl 卻完全沒有回應
curl http://127.0.0.1
request 卡住
* Connected to 127.0.0.1 > GET / HTTP/1.1
完全沒有 response…
重啟後問題更奇怪
這時候還想說會不會重開就沒事了 XD 於是決定 reboot server。
重開後檢查服務:
- Apache – 一樣顯示有在服務,但就是沒有回應(後來發現等久一點有可能有回應
- PM2 – 沒有回復上次 saved 的狀態
從瀏覽器連進去看看,發現其實可以連上,只是非常慢。這個時候我進入一個需要 MySql 的頁面,發現連 MySql 也掛了,甚至 SSH 也莫名的慢,才想說搞不好是硬碟滿了 XDDD
檢查硬碟空間
先檢查 disk usage:
df -h
結果看到:
Filesystem Size Used Avail Use% Mounted on /dev/vda1 25G 24G 0 100% /
Root disk 已經滿了。
接下來想撈出大檔並排序:
$ sudo du -ah / | sort -rh | head -20
但 ubuntu 回我:
sort: write failed: /tmp/sortwWBWJH: No space left on device
連一點點空間都沒了,沒辦法做 temp 導致 sort 都掛了…
求救 ChatGPT,先用以下方式釋放出一些空間:
清理 apt cache:
sudo apt clean
清掉系統 Log 只保留 500MB 日誌:
sudo journalctl --vacuum-size=50M
清理 Docker
docker system prune -af docker volume prune -f
這樣就有約 300mb 可使用。
接下來尋找大型檔案:
sudo find / -xdev -type f -size +100M -exec ls -lh {} \;
結果看到:
/var/lib/docker/.../json.log 308M /home/xxxxx/.pm2/pm2.log 8.0G /home/xxxxx/.pm2/logs/...error.log 1.4G
問題立刻浮現… PM2 log 爆掉了….
PM2 log 竟然長到 8GB
PM2 預設會持續寫 log。如果沒有設定 log rotation,log 會一直增加。
這台 server 的情況:
~/.pm2/pm2.log → 8GB error log → 1.4GB
直接把小小的硬碟撐爆。附帶一提這台硬碟只有 20G !
來清垃圾囉
先清空 PM2 log:
pm2 flush
或也可以這樣清空:
truncate -s 0 ~/.pm2/pm2.log
另外也發現 Docker log 有 300 多 mb 順便清一下
sudo truncate -s 0 /var/lib/docker/containers/*/*.log
清理後磁碟狀態
再次檢查:
df -h
結果:
Filesystem Size Used Avail Use% Mounted on /dev/vda1 25G 14G 9.7G 59% /
硬碟使用率從 100% → 59%,釋放將近 10GB 空間。
重啟後,所有服務都能正常啟動了!
PM2 log rotation
為了避免再次發生,我們可以安裝 PM2 log rotation 安裝官方 module:
pm2 install pm2-logrotate
設定
pm2 set pm2-logrotate:max_size 10M pm2 set pm2-logrotate:retain 10
Docker log rotation
編輯:
/etc/docker/daemon.json
加入:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
然後重啟 Docker。
結論
這次的事件其實是很基本的問題,只是一開始沒料到硬碟竟然被塞滿(忘記他很小),所以排查的方向一直是錯的。在加大硬碟之前,以後排查 server 問題時,第一件事就先跑:
df -h
有時候問題真的比想像中簡單 XDDD




