适用于 Linux 上排查 df 显示文件系统接近满载、但 du 汇总明显较小的情况。命令基线为 GNU coreutils 8.32+、util-linux 2.36+;lsof 为可选工具,示例挂载点为 /,执行前应替换为实际目标。先采集证据,不要一开始就删除文件或重启整机。
1. 先确认满的是空间还是 inode
date -u
df -hT /
df -ih /
findmnt -T / -o TARGET,SOURCE,FSTYPE,OPTIONS
Use% 接近 100% 表示数据块紧张;IUse% 接近 100% 表示 inode 紧张,常见原因是大量小文件。findmnt 用于确认后续命令针对的真实文件系统,避免把容器层、临时挂载或其他分区混在一起。
2. 用同一文件系统口径汇总目录
sudo du -xhd1 / 2>/dev/null | sort -h
sudo du -xhd1 /var 2>/dev/null | sort -h
-x 禁止跨越文件系统边界,因此结果才适合和目标文件系统的 df 对照。若 inode 满而空间并不大,可改看:
sudo du --inodes -x -d1 / 2>/dev/null | sort -n
大目录应继续逐层下钻,不要直接用不限制范围的 find /,生产主机上全盘遍历可能产生明显 I/O。
3. 检查“已删除但仍被进程打开”的文件
sudo lsof -nP +L1
这类文件已经不在目录树中,所以 du 看不到;只要进程仍持有文件描述符,文件系统就不会释放对应块。重点记录 COMMAND、PID、FD、SIZE/OFF 和路径。
没有 lsof 时可先做只读确认:
sudo find /proc/[0-9]*/fd -lname '* (deleted)' -printf '%p -> %l\n' 2>/dev/null
修复应针对持有者:让服务按其文档重新打开日志,或在确认可恢复后重启该单个服务。不要直接截断 /proc/<pid>/fd/<n>;文件描述符可能不是日志,写入或截断会破坏进程状态。操作后重新运行 lsof +L1 和 df -hT,确认占用确实下降。
4. 排除挂载点遮住底层文件
findmnt -R /
mountpoint /var/lib/example
如果应用先向目录写入大量数据,随后又把另一个文件系统挂到同一路径,底层文件仍占用原文件系统,但普通 du 只能看到挂载后的内容。不要为检查而直接卸载生产挂载;应在维护窗口或独立挂载命名空间中查看底层目录,并先确认相关服务不会继续写入。
5. 按文件系统类型检查额外占用
ext4 可能保留一部分块供特权进程使用。只读查看:
SOURCE=$(findmnt -T / -n -o SOURCE)
sudo tune2fs -l "$SOURCE" 2>/dev/null | \
grep -E 'Block count|Reserved block count|Block size'
仅当 FSTYPE 为 ext2/ext3/ext4 时使用 tune2fs。保留块不是异常,也不要在没有容量规划和恢复空间的前提下直接修改比例。Btrfs、ZFS 以及带快照的存储应使用各自的空间统计工具;CoW、快照和配额会使 df 与目录级 du 不再是一一对应关系。
6. 闭环标准
一次排查至少应留下这组结果:
- 明确问题是数据块、inode,还是两者同时紧张。
df、du -x与findmnt针对同一个文件系统。- 已删除但仍打开的文件、隐藏在挂载点下的文件、快照或保留块均已逐项确认。
- 处理后再次记录
df -hT、df -ih,并确认相关服务仍正常写日志和响应健康检查。
如果释放后空间很快再次增长,应继续定位增长速率和文件创建者,而不是把定期删除文件当作最终修复。