服务器磁盘满了怎么查:df、du、lsof 的排查顺序
先看 df:是空间满了,还是 inode 满了
收到磁盘告警后,第一步不是删文件,而是确认哪一类资源耗尽。空间和 inode 是两回事,处理方式也不同。
df -h
df -i
df -h 看的是块空间。如果 Use% 已经到了 100%,但 du 统计出来的总量并不大,通常是“文件已删除但进程还占着句柄”。df -i 看的是 inode;如果 Inodes 的 IUse% 满了,即使还有空间,也创建不了新文件,常见于缓存目录里堆了大量小文件。
用 du 逐层定位大目录
确认是空间问题后,从根目录开始一层层往下看。-x 表示不跨文件系统,避免把挂载的磁盘也算进来;-d1 表示只统计一层:
sudo du -xhd1 / | sort -h
sudo du -xhd1 /var | sort -h
找到最大的目录后再进入下一层,重复同样的命令。不要一上来就对整个根目录跑 du -sh,文件多的时候会很慢。如果服务器上装了 ncdu,交互式查看会更直观。
df 和 du 对不上:用 lsof 找已删除文件
这是最容易被忽略的一种情况:日志文件被 rm 掉了,但写日志的进程还没有重启,文件句柄仍然存在,磁盘空间不会释放。此时 df 显示快满了,du 却找不到对应的大文件。
sudo lsof +L1 | grep -i deleted | sort -k7 -n | tail -20
+L1 表示列出链接数小于 1 的文件。找到对应进程后,重启该进程,或者对文件执行 truncate -s 0,空间就会释放。直接再次 rm 是没用的,因为文件已经不在目录项里了。
常见场景一:journald 日志
systemd 的 journal 日志默认会占用一定空间。先看用量,再按大小或时间清理:
journalctl --disk-usage
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=7d
长期方案是在 /etc/systemd/journald.conf 里设置 SystemMaxUse,避免再次涨满。
常见场景二:应用日志
正在被进程写入的日志,不要直接 rm。要么让应用支持重新打开日志文件,要么用 logrotate 的 copytruncate,要么直接清空:
sudo truncate -s 0 /var/log/myapp/app.log
清空之后要补上轮转策略,否则过几天还会满。按天切分、保留 14 天、压缩旧文件,是比较通用的配置。
常见场景三:Docker
Docker 的 json-file 日志默认不限制大小,容器跑久了很容易把 /var/lib/docker 撑大。先看整体占用:
docker system df
sudo du -sh /var/lib/docker/*
长期方案是在 /etc/docker/daemon.json 里限制单个日志文件的大小和数量,例如 max-size: 100m、max-file: 3,然后重启 Docker。已经有的大日志需要单独清理,配置只对之后的写入生效。
一个固定的排查顺序
df -h和df -i:确认是空间还是 inode;du -xhd1逐层定位最大的目录;lsof +L1检查已删除但仍被占用的文件;- 按场景清理 journald、应用日志或 Docker 日志;
- 清理后再次
df -h确认,并补上轮转或限额配置。
磁盘告警本身不可怕,可怕的是上来就删文件,删错了业务数据,空间却没释放。按这个顺序走,通常几分钟就能定位到真正的原因。
- 点赞
- 收藏
- 关注作者
评论(0)