Linux 服务器 df 显示磁盘满了,却找不到大文件,是什么原因?
问题
根分区 df 一看已经 100%,进系统用 du 从根目录一层层加下来,数字却对不上,占空间的大文件死活找不到。空间到底被谁吃了?
原因
df 满而 du 找不到,说明空间被"看不见的文件"占了,主要是两类:
- 被挂载点"盖住"的文件。某个目录(比如 /data)在数据盘还没挂载时被写进了大文件,之后新盘挂载到这个目录上,旧文件仍在磁盘原地,但被挂载挡住,du 从上层根本扫不到。
- 已删除但仍被进程占用的文件。文件被 rm 删了,进程没关掉它的句柄,空间不释放,df 继续统计——这类文件 du 同样看不到。先走哪类,一条命令就能分流。
解决
第一步:df -h 确认满的是哪个分区(最常见是根分区 /),别对着别的分区白忙活。
第二步:lsof +L1 | sort -k7 -rn | head 列出"已删除仍被持有"的文件。有命中就 ps -fp <PID> 看是哪个进程,systemctl restart <服务名> 重启它,句柄一放空间马上回来,结案。
第三步:没有 deleted 文件,就按"挂载遮蔽"查。用 du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -20 从根往下逐层看(-x 表示不跨分区统计),找到"df 显示满、du 数字却很小"的目录,多半是 /mnt、/data 这类挂载点。
第四步:验证并处理。先 lsof +D /挂载点 确认没有进程正在使用,再 umount /挂载点 卸下,然后 ls -lah /挂载点/——被盖住的大文件现形;确认无用就删掉或挪走,最后 mount -a 按配置挂回。
第五步:df -h 复核空间已释放;顺手 df -i 看一眼 inode 使用率,小文件把 inode 耗尽也是"满了却找不到大文件"的一种变体。
预防
- 挂数据盘之前养成确认习惯:
mount | grep 目录确认盘已挂上再写数据;挂载点目录里不放业务文件,从源头避免遮蔽。 - 部署时把日志、数据目录放独立分区,配一个使用率超过 85% 就告警的小脚本,别等满了才上手。
- 历史日志和冷数据定期归档到专门的备份存储(比如一台 RS2423+),别让根分区当仓库。