记一次生产事故--磁盘被占满

写在前面

今天,跑在阿里云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服务产生的日志文件。

最后,有一个专业的运维是多么重要!

你可能感兴趣的:(技术)