記一次生產事故 磁碟被佔滿

ITLearner發表於2020-02-10

寫在前面

今天,跑在阿里雲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資料庫資料目錄移動到系統盤

參考如何將PostgreSQL資料目錄移動到Ubuntu 16.04上的新位置

$ 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服務產生的日誌檔案。

最後,有一個專業的運維是多麼重要!

相關文章