Linux服务器磁盘空间异常如何用df与du验证:看挂载点和目录占用

当 Linux 服务器提示磁盘空间不足时,先不要直接删除日志、缓存或临时文件。需要先回答两个问题:到底是哪一个文件系统的可用空间不足,以及这个文件系统中的哪些目录或文件占用了空间。df 和 du 分别从文件系统层面和目录树层面提供证据,只有在确认同一个挂载点后进行对照,结果才有判断价值。
推荐的低风险排查顺序是:先用 df 找出异常文件系统,再用 findmnt 确认目标路径对应的挂载点,随后从该挂载点开始使用带 -x 的 du 分层扫描。若 df 显示接近满载而 du 找不到相应目录,再检查权限错误、已删除但仍被进程打开的文件、挂载点遮蔽、inode 耗尽以及文件系统内部空间。
先确认异常文件系统和实际挂载点
以下命令适用于常见 Linux 服务器,默认使用 GNU 版本的 df、du 和 findmnt。目录统计可能需要读取其他用户或系统服务创建的文件,建议使用具有只读排查权限的 sudo。这些检查命令不会主动删除或修改业务数据。
假设业务反馈 /var 空间不足,先设置目标路径:
TARGET=/var
查看该路径所在文件系统的容量、类型、inode 使用率和挂载信息:
df -PTh "$TARGET"
df -ih "$TARGET"
findmnt -T "$TARGET" -o TARGET,SOURCE,FSTYPE,OPTIONS
重点查看以下字段:
Filesystem:文件系统来源,可能是设备、逻辑卷、网络文件系统或其他挂载来源。Type:文件系统类型,用于判断后续差异是否可能与文件系统特性有关。Size、Used、Avail、Use%:文件系统层面的容量和使用情况。Mounted on:本次df统计对应的挂载点。IUse%:inode 使用率。inode 耗尽时,即使仍有可用字节,也可能无法创建新文件。OPTIONS:挂载选项,可辅助判断文件系统是否以只读方式挂载。
如果故障表现为根分区空间不足,将目标改为 /:
TARGET=/
df -PTh "$TARGET"
df -ih "$TARGET"
findmnt -T "$TARGET" -o TARGET,SOURCE,FSTYPE,OPTIONS
不要仅凭路径名称判断文件属于哪个分区。/var 可能是根文件系统中的普通目录,也可能是单独挂载的文件系统。可以进一步查看系统的挂载关系:
findmnt -R /
对具体路径执行以下命令进行交叉确认:
findmnt -T /var/log -o TARGET,SOURCE,FSTYPE,OPTIONS
df -PTh /var/log
findmnt -T /var/log 会显示该路径实际归属的挂载点,df -PTh /var/log 则统计该路径所在的文件系统。如果 /var 是独立挂载点,那么下面两个命令可能返回不同的文件系统:
df -PTh /
df -PTh /var
这时,根文件系统中的 /var 挂载点本身不能代表 /var 文件系统的全部占用;同样,扫描 /var 文件系统时也不会把它的空间计入根文件系统。
挂载点判断标准
| 观察结果 | 判断与下一步 |
|---|---|
df / 使用率高,df /var 正常 | 优先检查根文件系统中的其他目录,不能只扫描 /var |
df /var 使用率高,且 /var 是独立挂载点 | 从 /var 开始使用 du -x 扫描 |
多个路径返回相同的 Filesystem 和挂载点 | 这些路径共享同一个文件系统,应合并判断 |
df -h 尚有空间,但 df -i 的 IUse% 接近或达到满值 | 重点检查大量小文件和 inode,不要只查大文件 |
findmnt 显示目标路径为只读挂载 | 空间清理不能直接解决写入失败,应先核实只读原因和挂载状态 |
如果故障发生在容器、chroot 或其他独立挂载命名空间中,必须在报告故障的同一环境执行命令。宿主机和容器看到的挂载表可能不同,不能用宿主机的 df 结果直接代替容器内结果。
以目标挂载点为边界执行 du
确认目标挂载点后,从该挂载点的第一层目录开始扫描。对根文件系统执行:
sudo du --one-file-system --human-readable --max-depth=1 / \
2>/tmp/du-root.err | sort -h
对独立挂载的 /var 执行:
sudo du --one-file-system --human-readable --max-depth=1 /var \
2>/tmp/du-var.err | sort -h
常用的短参数写法是:
sudo du -xhd1 /var 2>/tmp/du-var.err | sort -h
参数含义如下:
-x或--one-file-system:限制在当前文件系统内,不跨入其他文件系统。-h或--human-readable:使用便于阅读的容量单位。-d1或--max-depth=1:先列出当前目录和下一层目录,避免第一次扫描输出过多。sort -h:按可读容量排序,大目录通常位于输出末尾。2>/tmp/du-var.err:保存权限不足、文件消失或特殊文件导致的错误,避免把未统计到误认为没有占用。
du 的起点必须与待比较的文件系统一致。检查根文件系统时使用:
sudo du -xhd1 / 2>/tmp/du-root.err | sort -h
检查 /var 文件系统时使用:
sudo du -xhd1 /var 2>/tmp/du-var.err | sort -h
不要直接用未加 -x 的命令扫描根目录:
sudo du -hd1 /
如果 /var、/home 或其他目录是独立挂载点,未加 -x 的扫描可能继续进入这些文件系统,将其他挂载点的目录占用混入根文件系统统计。此时结果不能直接与 df / 对比。
从第一层目录找到大目录后,再继续向下扫描:
sudo du -xhd1 /var/lib 2>/tmp/du-var-lib.err | sort -h
sudo du -xhd1 /var/log 2>/tmp/du-var-log.err | sort -h
定位到具体路径后,可查看该目录在当前文件系统内的总量:
sudo du -shx /var/lib/example
sudo du -shx /var/log/example
其中的路径应替换为实际扫描结果,不要在尚未确认用途的目录上直接执行删除或清空操作。
对照 df 与 du,判断空间异常类型
df 统计文件系统层面的已用块和可用空间,du 统计目录树中能够遍历到的文件占用。两者数值不要求完全相等:文件系统元数据、日志结构、预留空间,以及扫描期间仍在变化的文件,都可能造成差异。有效判断的前提是:两条命令针对同一个文件系统、相同的挂载环境,并且 du 没有明显读取错误。
df 表现 | du 表现 | 优先判断 |
|---|---|---|
| 使用率高 | 也能找到一个或多个大目录 | 文件系统中存在可见的大文件或大目录,继续向下定位 |
| 使用率高 | 明显偏低 | 检查已删除但仍打开的文件、挂载点遮蔽、权限错误和文件系统内部占用 |
| 字节空间尚可 | inode 使用率接近满值 | 可能是大量小文件,而不是少数大文件 |
du 结果每次变化 | 目录内容持续写入或删除 | 在业务状态稳定后重复采集,不能只依据一次扫描清理 |
du 错误输出较多 | 统计不完整 | 先处理权限、输入输出错误或不可访问目录,再解释差异 |
df 高、du 也高:继续从大目录向下定位
如果 df 显示目标挂载点接近满载,du 也找到相应的大目录,通常说明空间确实被可见文件占用。继续按从大到小的顺序执行:
sudo du -xhd1 /var
sudo du -xhd1 /var/lib
sudo du -xhd1 /var/lib/example
需要核对:
- 大目录是否属于预期的业务或系统服务。
- 是否存在异常增长的日志、临时文件、缓存或备份文件。
- 文件修改时间和所属用户是否与故障发生时间相符。
- 目录是否仍位于目标挂载点,而不是另一个文件系统。
- 文件是否仍被业务进程读取或写入。
如果怀疑是少数大文件,可以先只读筛选:
sudo find /var -xdev -type f -size +1G -printf '%s %p\n' \
2>/tmp/find-large.err | sort -n
该命令只查找 /var 文件系统内大于指定大小的普通文件。+1G 只是筛选条件,不代表所有异常都由大文件造成;inode 耗尽时,问题可能来自大量小文件。find-large.err 中的错误也要一并查看,否则权限不足的目录可能被遗漏。
df 高、du 明显偏低:按优先级排查差异来源
先查看 du 的错误输出:
sudo sed -n '1,80p' /tmp/du-var.err
如果存在大量 Permission denied、Input/output error 或目录无法访问,当前 du 结果不完整,不能据此决定清理范围。确认扫描无明显错误后,再按以下顺序检查。
第一,确认扫描没有跨错文件系统。 检查 findmnt -T "$TARGET" 的结果,并确保 du 从同一个挂载点开始,同时带有 -x。例如,比较 /var 时,不能用扫描整个 / 的结果代替:
findmnt -T "$TARGET" -o TARGET,SOURCE,FSTYPE,OPTIONS
df -PTh "$TARGET"
sudo du -xhd1 "$TARGET" 2>/tmp/du-check.err | sort -h
第二,检查已删除但仍被进程打开的文件。 文件从目录中删除后,只要进程仍持有文件描述符,已分配的磁盘块通常不会立即释放。du 无法从目录树中看到这类文件,但 df 仍会显示空间已使用。
如果系统已安装 lsof,执行:
sudo lsof -nP +L1
重点查看:
SIZE/OFF是否很大;COMMAND、PID和USER对应哪个服务;NAME是否包含(deleted);- 文件属于日志、临时文件还是业务数据。
不要直接删除 /proc/ 下的文件。应先确认服务的日志轮转或文件重开方式;如果必须重启服务,需要确认业务影响、维护窗口、配置备份和启动回滚方案。服务关闭并释放文件描述符后,再重复执行 df 和 du,确认空间是否真正释放。
第三,检查挂载点是否遮蔽了底层目录。 挂载文件系统后,挂载点目录原有的文件不会自动删除,但在挂载期间不可见。例如,/var 挂载了新的文件系统后,根文件系统原本的 /var 内容会被遮住。此时扫描挂载后的 /var 看不到底层文件,但这些文件仍可能占用根文件系统空间。
先确认挂载关系:
findmnt -T /var
df -PTh /
df -PTh /var
如果根文件系统使用率很高,而独立挂载的 /var 内部占用并不高,就需要进一步核对被遮蔽的底层目录。生产环境不要直接执行:
sudo umount /var
直接卸载可能导致服务无法访问配置、日志或运行数据。
在确认权限、挂载关系和命名空间行为后,可以使用临时的私有挂载命名空间进行只读排查:
sudo unshare --mount --propagation private /bin/sh
进入临时 shell 后,先再次确认路径,再执行卸载和统计:
findmnt -T /var
umount /var
du -shx /var
exit
这里的卸载只作用于临时挂载命名空间;退出 shell 后不会保留该命名空间中的变更。只有在确认 /var 确实是挂载点,并且 unshare 创建的是私有命名空间时,才适合采用此方法。如果系统不支持该命令、卸载失败,或无法确认命名空间状态,应安排维护窗口,在备份或救援环境中检查,不要改用生产环境的直接卸载。
第四,检查 inode 是否耗尽。 如果 df -h 显示仍有可用空间,但 df -i 的 IUse% 已达到上限,问题通常是文件数量过多,而不是单个文件太大。可以先粗略统计目标文件系统内的普通文件数量:
sudo find /var -xdev -type f -printf '%p\n' \
2>/tmp/find-files.err | wc -l
该命令只统计普通文件,不等同于完整的 inode 统计,也可能因权限错误而遗漏内容。目录文件量很大时,扫描可能需要较长时间,应在可接受的时段执行。找到文件数量异常的目录后,还要结合文件生命周期、应用配置和保留策略处理,不能仅凭文件数量直接删除。
第五,考虑文件系统内部空间和统计时机。 如果 du 无明显错误,已删除打开文件和挂载点遮蔽也已排除,但两者仍有较大差异,差异可能来自文件系统元数据、日志、预留空间或其他文件系统内部结构。此时不要用 du 的目录总量推断全部可回收空间,也不要在没有文件系统类型、备份和维护窗口的情况下执行修复或调整预留空间的操作。可以先重复采集 df、du 和 findmnt,确认问题是否因业务持续写入而变化。
修复动作、影响范围与回滚
df、du、findmnt 以及大部分 find 查询命令本身不会修改业务数据。真正的空间释放动作,例如删除日志、清空缓存、压缩文件、调整日志轮转或重启服务,应按以下顺序进行:
- 记录异常文件的路径、大小、所属用户、修改时间和对应服务。
- 确认文件是可重建缓存、已归档日志,还是仍被业务读取的数据。
- 对不可替代的数据先完成备份、快照或其他可恢复副本。
- 明确操作影响范围,必要时停止服务或安排维护窗口。
- 执行最小范围的清理或日志轮转,不要对未知路径使用通配符批量删除。
- 保留操作记录,并准备通过备份恢复、撤销配置变更或重新挂载进行回滚。
已删除文件、日志轮转和服务重启通常没有通用的“撤销删除”命令。删除前未保留副本时,能否回滚取决于备份、快照或应用自身的数据恢复机制。因此,排查阶段应优先使用 df、du 和 findmnt 建立证据,避免把诊断命令和清理命令混在一起。
修复后重复验证同一个挂载点
完成清理或服务处理后,必须针对原来的同一个挂载点重新验证:
TARGET=/var
df -PTh "$TARGET"
df -ih "$TARGET"
findmnt -T "$TARGET" -o TARGET,SOURCE,FSTYPE,OPTIONS
sudo du -xhd1 "$TARGET" 2>/tmp/du-after.err | sort -h
如果之前发现了已删除但仍被打开的文件,再次检查:
sudo lsof -nP +L1
验证结果应同时满足以下条件:
- 目标挂载点的
Use%下降,Avail增加。 IUse%不再处于满值或异常增长状态。du显示的大目录与当前业务预期一致。du-after.err没有新的关键权限错误或输入输出错误。- 目标服务能够正常写入日志、临时文件或业务数据。
findmnt显示的挂载点、文件系统来源和挂载选项没有被误改。- 如果使用了私有挂载命名空间排查,退出后生产环境的挂载表保持不变。
上线或验收检查清单
- [ ] 已用
df -PTh确认实际异常的文件系统和挂载点。 - [ ] 已用
df -ih排除 inode 耗尽,而不只是检查字节空间。 - [ ] 已用
findmnt -T验证待查路径的真实挂载归属。 - [ ] 已从目标挂载点开始使用
du -x,没有把其他文件系统混入统计。 - [ ] 已检查
du的错误输出,没有把权限错误误判为目录为空。 - [ ] 已对照
df与du,并解释两者之间的差异。 - [ ]
df高而du低时,已检查已删除但仍打开的文件和挂载点遮蔽。 - [ ] 所有删除、压缩、日志轮转或重启操作都有明确影响范围、备份和恢复方案。
- [ ] 修复后已重复检查容量、inode、挂载状态和业务写入能力。