Linux 磁盘空间告急排查实战:df、du 与“删了文件却不释放”的真相
服务器报警“磁盘使用率 95%”,是运维最常遇到的场景之一。本文整理一套从粗到细的排查流程,并解释一个经典坑:文件明明删了,空间却没回来。
1. 先看整体:df
df -hT
df -ih
df -hT 查看各文件系统的容量和类型,df -ih 查看 inode 使用率。有时磁盘容量还有富余,但 inode 耗尽(海量小文件),同样会报 “No space left on device”。如果 inode 使用率接近 100%,重点找小文件密集的目录,例如缓存目录、会话目录、邮件队列。
2. 逐层下钻:du
sudo du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -10
-x 表示不跨文件系统,避免把挂载的其他盘算进来;--max-depth=1 只统计一层;sort -rh 按人类可读的大小倒序。找到最大的目录后,继续对它重复同一条命令,几轮就能定位到具体位置。常见嫌疑目录有 /var/log、/var/lib/docker、/tmp、/home。
如果机器上能装工具,ncdu 提供交互式界面,用方向键就能逐层进入,效率更高。
3. 找出大文件
sudo find /var -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null
这条命令会列出 /var 下超过 500MB 的文件。日志、数据库备份、core dump 是最常见的“大头”。
4. 删了文件空间不释放?
现象:du 统计的总量远小于 df,或者刚删除了几个 GB 的日志,df 却纹丝不动。原因通常是:文件已被删除,但仍有进程打开着它,内核要等所有句柄关闭后才会真正回收空间。
sudo lsof +L1 | grep -i deleted
+L1 会列出链接数小于 1 的已打开文件,也就是已删除但仍被占用的文件。输出里能看到进程名、PID 和文件大小。处理方式有两种:
- 重启或重载对应的服务,让它重新打开日志文件,句柄随之释放。
- 不方便重启时,可以清空文件而不是删除:
: > /proc/PID/fd/FD编号。这会把已删除文件截断为 0,空间立即回收。
经验是:清理日志时优先用 truncate -s 0 文件名 或 : > 文件名,而不是 rm,这样即使进程还在写,也不会出现“幽灵文件”。
5. 常见的治本措施
- 配置 logrotate:按大小或时间切割日志,设置保留份数并压缩。
- 限制 journald 占用:在
/etc/systemd/journald.conf中设置SystemMaxUse=500M。 - 定期清理 Docker:
docker system df查看占用,docker image prune、docker builder prune清理无用镜像和构建缓存。 - 加监控:磁盘使用率超过 80% 就告警,而不是等到 95%。
小结
排查顺序可以记成四步:df 看整体和 inode,du 逐层下钻,find 找大文件,lsof +L1 排查已删除但被占用的文件。把这套流程固化成习惯,磁盘告警就不再手忙脚乱。
- 点赞
- 收藏
- 关注作者
评论(0)