ZZTEXTMARKER

Linux 服务器 df 显示磁盘满了,却找不到大文件,是什么原因?

问题

根分区 df 一看已经 100%,进系统用 du 从根目录一层层加下来,数字却对不上,占空间的大文件死活找不到。空间到底被谁吃了?

原因

df 满而 du 找不到,说明空间被"看不见的文件"占了,主要是两类:

  1. 被挂载点"盖住"的文件。某个目录(比如 /data)在数据盘还没挂载时被写进了大文件,之后新盘挂载到这个目录上,旧文件仍在磁盘原地,但被挂载挡住,du 从上层根本扫不到。
  2. 已删除但仍被进程占用的文件。文件被 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+),别让根分区当仓库。