首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >df 显示磁盘已满但 du 对不上:已删除文件仍被进程占用的排查与释放

df 显示磁盘已满但 du 对不上:已删除文件仍被进程占用的排查与释放

原创
作者头像
一只特立独行的兔先生
发布于 2026-10-29 22:08:11
发布于 2026-10-29 22:08:11
560
举报

现象

云服务器上磁盘告警,df -h 显示数据盘使用率 100%,但在挂载目录下执行 du -sh 统计,总量却只有一半左右。删除了大日志文件后,可用空间也没有增加。这类问题通常有几种原因,本文按排查顺序整理。

原因一:文件已删除但仍被进程打开

Linux 中 rm 只是删除目录项。只要还有进程持有该文件的打开句柄,inode 和数据块就不会释放,df 仍按占用统计,而 du 遍历目录时看不到这个文件,于是两个数字对不上。

典型场景:用 rm 直接删除了仍在被写入的日志,而日志进程没有重新打开文件。

排查

代码语言:bash
复制
# 列出链接数为 0(已删除)但仍被打开的文件
lsof +L1

# 只看某个挂载点
lsof -nP +L1 /data

输出里带 (deleted) 的行,关注 PID、FD 和 SIZE/OFF 两列。没有安装 lsof 时,可以直接查看 /proc:

代码语言:bash
复制
ls -l /proc/*/fd 2>/dev/null | grep '(deleted)'

释放空间

  1. 首选让进程重新打开日志,例如 Nginx 执行 nginx -s reopen,或发送程序约定的信号;也可以重启对应服务。
  2. 无法重启时,可以直接清空被占用的文件,空间会立即释放:
代码语言:bash
复制
# 将 PID 与 FD 替换为 lsof 输出中的实际值
: > /proc/<PID>/fd/<FD>

注意:这会丢弃该文件的全部内容,操作前确认数据确实不需要。

原因二:目录被挂载点遮盖

如果先往 /data 下写了文件,之后才把数据盘挂载到 /data,原目录里的文件会被新挂载遮住,du 看不到,但它们占用的是根分区。可以用 bind mount 查看底层内容:

代码语言:bash
复制
mkdir -p /mnt/rootfs && mount --bind / /mnt/rootfs
du -sh /mnt/rootfs/data
umount /mnt/rootfs

原因三:inode 耗尽

df -h 显示还有空间,却报 No space left on device,要看 inode:

代码语言:bash
复制
df -i

IUse% 接近 100% 说明小文件过多,需要清理目录下的海量小文件(例如缓存、会话文件)。

原因四:du 本身统计不到的内容

  • du 默认不跨文件系统时需要加 -x,否则会把其他挂载点也算进去,造成反向的不一致。
  • 稀疏文件和硬链接会让 du 与 ls -l 的大小不同,比较时注意 --apparent-size 选项的差别。
  • 容器场景下,Docker 的镜像层和容器日志位于 /var/lib/docker,可以用 docker system df 查看占用。

推荐排查顺序

  1. df -h 与 df -i 确认是容量还是 inode 问题。
  2. du -xh --max-depth=1 /data | sort -h 逐层定位大目录。
  3. lsof +L1 检查已删除但未释放的文件。
  4. 检查是否存在被挂载遮盖的目录。
  5. 云硬盘容量确实不足时,再到控制台扩容,并在系统内扩展分区与文件系统。

预防

  • 清理日志用 truncate -s 0 文件名 或 logrotate 的 copytruncate,避免直接 rm 正在写入的文件。
  • 为日志目录配置 logrotate,并在 postrotate 中让服务重新打开日志。
  • 给磁盘使用率和 inode 使用率都设置监控告警,阈值按业务情况调整。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 现象
  • 原因一:文件已删除但仍被进程打开
    • 排查
    • 释放空间
  • 原因二:目录被挂载点遮盖
  • 原因三:inode 耗尽
  • 原因四:du 本身统计不到的内容
  • 推荐排查顺序
  • 预防
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档