寫在前面
今天,跑在阿里雲ECS上的生產環境,突然間訪問異常,介面各種報錯,無奈公司沒有專業的運維人員,只能硬著頭皮解決一下。
問題排查
先從表面看起,資料庫首先報錯
Caused by: org.postgresql.util.PSQLException: ERROR: could not extend file "base/16385/16587_fsm": No space left on device
建議:Check free disk space.
複製程式碼
直觀上看,裝置沒有可用空間,也就是磁碟滿了。
進入伺服器後臺,執行
$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 7.9G 0 7.9G 0% /dev
tmpfs 1.6G 3.5M 1.6G 1% /run
/dev/vda1 59G 56G 0 100% /
tmpfs 7.9G 4.0K 7.9G 1% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
/dev/mapper/vg0-vol0 1000G 14G 937G 2% /data
tmpfs 1.6G 0 1.6G 0% /run/user/0
複製程式碼
發現確實磁碟滿了,而且滿的很徹底。系統盤佔用100%,估計什麼服務都跑不動了。/dev/vda1 59G 56G 0 100% /
不過發現/dev/mapper/vg0-vol0 1000G 14G 937G 2% /data
,1000G只用了2%
阿里雲ECS分為系統盤和資料盤,1000G的是資料盤
第一反應,應該是搭建的PG資料庫的資料沒有移到資料盤上。
將Postgres資料庫資料目錄移動到系統盤
$ sudo -u postgres psql
postgres# SHOW data_directory; # 檢視當前資料目錄
data_directory
------------------------------
/var/lib/postgresql/9.5/main
(1 row)
postgres# \q; # 退出
# 為了確保資料的完整性,我們將在實際更改資料目錄之前關閉PostgreSQL
$ sudo systemctl stop postgresql
# 確保關閉完成
$ sudo systemctl status postgresql
. . .
Jul 22 16:22:44 ubuntu-512mb-nyc1-01 systemd[1]: Stopped PostgreSQL RDBMS.
$ sudo rsync -av /var/lib/postgresql /data # /data為要遷移到的新目錄
$ cd /data
$ ls
... postgresql
# 刪除原資料目錄
$ sudo rm -rf /var/lib/postgresql
# 將新資料目錄連結到原資料目錄
$ sudo ln -s /data/postgresql /var/lib/postgresql
# 重啟Postgres資料庫
$ sudo systemctl start postgresql
$ sudo systemctl status postgresql
複製程式碼
完成以上步驟,即將postgre資料庫資料目錄移到了阿里雲資料盤
以為OK了,執行
$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 7.9G 0 7.9G 0% /dev
tmpfs 1.6G 3.5M 1.6G 1% /run
/dev/vda1 59G 56G 51M 100% /
tmpfs 7.9G 4.0K 7.9G 1% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
/dev/mapper/vg0-vol0 1000G 14G 937G 2% /data
tmpfs 1.6G 0 1.6G 0% /run/user/0
複製程式碼
紋絲未動。。。
Ubuntu查詢大檔案
猜測是存在大檔案導致磁碟被佔滿
$ cd /
$ find . -type f -size +800M -print0 | xargs -0 du -h
5.6G ./var/log/syslog.1
6.7G ./var/log/syslog
...
$ rm ...
複製程式碼
如果發現是log字眼的大檔案,我們可以毫不留情的刪掉,要是遇見一些不認識的,不要貿然刪掉,一定要查清楚檔案的作用,能刪則刪,千萬不要不小心刪庫跑路。。。
刪除完畢後,再次檢視
$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 7.9G 0 7.9G 0% /dev
tmpfs 1.6G 3.4M 1.6G 1% /run
/dev/vda1 59G 45G 12G 80% /
tmpfs 7.9G 4.0K 7.9G 1% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
/dev/mapper/vg0-vol0 1000G 14G 936G 2% /data
tmpfs 1.6G 0 1.6G 0% /run/user/0
複製程式碼
多出了12G。
檢視已刪除空間卻沒有釋放的程式
這時候,服務應該可以恢復成功。但你馬上會發現,磁碟又被佔滿,而這次,日誌檔案卻不算大。
檢視已經刪除的檔案,空間有沒有釋放,沒有的話kill掉pid
使用rm刪除檔案的時候,雖然檔案已經被刪除,但是由於檔案被其他程式佔用,空間卻沒有釋放
$ sudo lsof -n |grep deleted
java 17866 root 237r REG 253,1 163541 1709285 /tmp/tomcat.8250394289784312179.8080/work/Tomcat/localhost/ROOT/upload_c6db0c17_6e6a_4141_bfb6_ac1b2d8a3b0b_00000000.tmp (deleted)
...
$ sudo kill -9 17866
複製程式碼
再次使用df -h
命令,磁碟使用率一下子減少了好多。
總結
-
伺服器系統盤被佔滿是非常可怕的!屆時,一切服務都將變得不可用,業務系統也會莫名其妙多出奇怪的問題。所以,運維需要經常性的檢視伺服器磁碟佔用情況,阿里雲ECS使用者,可以開啟報警,及時發現問題,解決問題!
-
阿里雲ECS提供了系統盤和資料盤,記住,例如Pg、Redis、Cassandra等容易佔磁碟的服務,一定要將資料目錄放在阿里雲ECS提供的資料盤上。
-
/var/log
是系統日誌目錄,可以經常性的關注下,大容量日誌儘早刪除。 -
對待程式不停對檔案寫日誌的操作,要釋放檔案佔用的磁碟空間,最好的方法是線上清空這個檔案,可以通過如下命令完成:
[root@localhost ~]# echo "" >/var/log/syslog
複製程式碼
通過這種方法,磁碟空間不但可以馬上釋放,也可保障程式繼續向檔案寫入日誌,這種方法經常用於線上清理Apache、Tomcat、Nginx等Web服務產生的日誌檔案。
最後,有一個專業的運維是多麼重要!