写在前面
今天,跑在阿里云ECS上的生产环境,突然间访问异常,接口各种报错,无奈公司没有专业的运维人员,只能硬着头皮解决一下。
问题排查
先从表面看起,数据库首先报错
1 2
| Caused by: org.postgresql.util.PSQLException: ERROR: could not extend file "base/16385/16587_fsm": No space left on device 建议:Check free disk space.
|
直观上看,设备没有可用空间,也就是磁盘满了。
进入服务器后台,执行
1 2 3 4 5 6 7 8 9 10
| $ 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上的新位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| $ sudo -u postgres psql postgres data_directory ------------------------------ /var/lib/postgresql/9.5/main (1 row) postgres
$ 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 $ cd /data $ ls ... postgresql
$ sudo rm -rf /var/lib/postgresql
$ sudo ln -s /data/postgresql /var/lib/postgresql
$ sudo systemctl start postgresql $ sudo systemctl status postgresql
|
完成以上步骤,即将postgre数据库数据目录移到了阿里云数据盘
以为OK了,执行
1 2 3 4 5 6 7 8 9 10
| $ 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查询大文件
猜测是存在大文件导致磁盘被占满
1 2 3 4 5 6
| $ cd / $ find . -type f -size +800M -print0 | xargs -0 du -h 5.6G ./var/log/syslog.1 6.7G ./var/log/syslog ... $ rm ...
|
如果发现是log字眼的大文件,我们可以毫不留情的删掉,要是遇见一些不认识的,不要贸然删掉,一定要查清楚文件的作用,能删则删,千万不要不小心删库跑路。。。
删除完毕后,再次查看
1 2 3 4 5 6 7 8 9 10
| $ 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删除文件的时候,虽然文件已经被删除,但是由于文件被其他进程占用,空间却没有释放
1 2 3 4
| $ 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
是系统日志目录,可以经常性的关注下,大容量日志尽早删除。
对待进程不停对文件写日志的操作,要释放文件占用的磁盘空间,最好的方法是在线清空这个文件,可以通过如下命令完成:
通过这种方法,磁盘空间不但可以马上释放,也可保障进程继续向文件写入日志,这种方法经常用于在线清理Apache、Tomcat、Nginx等Web服务产生的日志文件。
最后,有一个专业的运维是多么重要!