VPS磁盘空间满了怎么排查是什么占用的
VPS用着用着突然报错No space left on device,很多人第一反应是"我这台VPS明明没存什么东西",其实占空间的往往不是自己上传的文件,日志、镜像缓存、容器这些"看不见"的东西悄悄堆积起来才是真正的元凶。
先看看是哪个分区满了
1 | df -h |
看输出里Use%这一列,哪个挂载点接近或者已经是100%,问题就出在那个分区上。
顺着目录往下找
确认了分区之后,从根目录开始一层层查:
1 | du -sh /* 2>/dev/null |
定位到某个大目录,接着往下钻:
1 | du -sh /目录路径/* 2>/dev/null |
重复几次就能缩小到具体是哪些文件在占空间。
真正排查下来,占大头的常常是Docker——跑过Docker的VPS,镜像层层叠加动辄占几个G甚至十几个G,docker system df能看到明细,确认没用的镜像和容器可以用docker system prune -a清掉(这个命令是真的会删东西,执行前看清楚)。系统日志没设大小限制的话也会一直往上涨,journalctl --vacuum-size=200M能把日志压到指定大小以内。包管理器下载过的安装包缓存(apt clean或者yum clean all)同样值得顺手清一遍。
df明明有空间,还是报错
有时候df -h显示分区还有剩余,却依然报No space left on device,这种情况大概率不是空间不够,是inode用完了:
1 | df -i |
IUse%这列如果接近100%,就是inode耗尽了,通常是某个目录堆了海量小文件(常见于日志切割没配置好,或者某个程序在疯狂生成临时文件),得去找的是文件数量多的目录,而不是找体积大的文件。
rm删了文件,空间却没变化
用rm删掉了一个大文件,df -h显示的空间却纹丝不动,是因为还有进程占着这个文件的文件描述符——文件从目录里消失了,底层数据块其实还没释放:
1 | lsof | grep deleted |
找到占用这个文件的进程,把对应的服务重启一下,空间才会真正被放出来。
一次性排查能解决眼前的问题,不想以后一直手动查的话,之前写过定期自动清理VPS,设置成定期自动跑,能少遇到一大半这种突然报错的情况。