df 显示磁盘已满,但 du 找不到大文件?Linux 磁盘空间排查实战
在 Linux 服务器运维中,经常会遇到一个令人困惑的问题:df -h 显示磁盘使用率已经 100%,但用 du -sh 逐级排查却找不到大文件。磁盘空间到底被谁"吃"掉了?本文总结 5 种常见原因和一套排查流程。
一、先分清:是"空间满"还是"inode 满"
df -h # 查看各分区空间使用率
df -i # 查看各分区 inode 使用率
如果 df -i 显示 IUse% 为 100%,说明是 inode 耗尽(通常由海量小文件导致),需要清理小文件;如果只是空间满但找不到大文件,继续往下看。
二、原因 1:已删除但仍被进程占用的文件(最常见)
文件被 rm 删除后,如果还有进程持有它的文件描述符,磁盘空间并不会真正释放,而 du 遍历目录时已经看不到这个文件,就会出现"df 满、du 找不到"的情况。日志文件被删除后服务未重启是典型场景。
排查:
lsof | grep deleted
处理:重启占用该文件的进程;或对 /proc/<pid>/fd/<fd> 执行清空操作(生产环境请谨慎,先确认进程可重建)。
三、原因 2:文件被挂载点"遮挡"
如果先在某个目录(如 /data)写入了文件,之后又把一块磁盘挂载到 /data,那么之前写入的文件会被挂载点遮住,du 统计不到,但空间照样被占用。
排查:
umount /data && du -sh /data # 卸载后检查(需确保业务允许)
# 或从宿主视角查看
mkdir -p /mnt/root && mount --bind / /mnt/root && du -sh /mnt/root/data
四、原因 3:稀疏文件与统计口径差异
du 按实际占用的数据块统计,df 按文件系统分配情况统计。稀疏文件(sparse file)、预分配但未写入的文件会让两者出现差异,但这种差异通常不会大到"找不到大文件"的程度,可作为次要排查项。
五、原因 4:其他挂载命名空间中的文件
容器内的进程写入的文件、或处于不同 mount namespace 的进程,对宿主机上的 du 可能是不可见的。排查时进入容器或对应命名空间再统计。
六、原因 5:文件系统保留块
ext4 等文件系统默认会为 root 用户保留约 5% 的空间,df 显示的"可用空间"已经扣除了保留块。这部分不是"丢失",但在磁盘将满时容易让人误判。
七、标准排查清单(按顺序执行)
df -h、df -i:确认是空间满还是 inode 满,定位到具体分区;lsof | grep deleted:查找已删除未释放的文件;- 检查挂载点遮挡:
mount | grep <分区>确认挂载关系; du -x --max-depth=1 /:用-x限定只统计本文件系统,避免跨分区干扰;- 检查容器 / 命名空间、保留块设置(
tune2fs -l)。
八、预防建议
- 日志使用 logrotate 做轮转和压缩,避免单个日志无限增长;
- 对磁盘使用率设置告警(如 80% 预警、90% 告警),别等到 100% 才处理;
- 定期巡检:把
df -h、df -i、lsof | grep deleted纳入日常巡检脚本。
遇到"df 满而 du 找不到"时,记住排查优先级:先看 inode,再查 deleted 句柄,最后查挂载遮挡,九成问题都能定位。
- 点赞
- 收藏
- 关注作者
评论(0)