Linux 磁盘空间告警怎么查?用 df、du、findmnt 三步定位
1. 背景:磁盘空间不足,不一定是大文件太多
在 Linux 云服务器上,磁盘空间告警可能带来一系列问题:
- 应用日志无法继续写入。
- 数据库或中间件因写入失败而报错。
- 临时文件创建失败,导致任务执行异常。
- 服务运行正常,但监控持续报告磁盘使用率过高。
面对这些现象,直接删除日志或临时文件并不是最佳做法。因为磁盘空间不足、inode 耗尽和挂载关系异常,是三个不同的问题,需要先区分原因,再决定如何处理。
本文采用只读排查流程:
- 使用
df确认哪个文件系统出现问题。 - 使用
findmnt确认目标目录实际位于哪个挂载点。 - 使用
du定位目录空间占用。 - 如果数据对不上,再检查 inode 和可能被进程继续占用的已删除文件。
GNU Coreutils 官方文档分别定义了 df 的文件系统空间统计能力,以及 du 对目录和文件空间使用量的估算方式。两者观察的对象不同,不能简单互相替代。
2. 第一步:用 df 确认哪个文件系统空间不足
2.1 查看磁盘空间使用率
先执行:
df -hT
主要关注以下字段:
| 字段 | 含义 |
|---|---|
| Filesystem | 文件系统来源 |
| Type | 文件系统类型 |
| Size | 文件系统总容量 |
| Used | 已使用空间 |
| Avail | 可用空间 |
| Use% | 空间使用率 |
| Mounted on | 挂载点 |
其中:
-h:使用便于阅读的容量单位。-T:显示文件系统类型。
GNU df -h 使用以 1024 为基数的容量单位,例如 G 对应 1024 的三次方字节,而不是十进制的 1000 的三次方字节。
假设输出中 /var 所在文件系统的使用率明显偏高,就应继续调查该文件系统中的日志、缓存、应用数据等目录,而不是立即清理整个系统。
如果想查看特定路径所在文件系统,可以执行:
df -hT /var
这里的 /var 只是示例路径。实际排查时,可以将其替换为 /, /var/log、应用数据目录或其他出现问题的路径。
注意:df 显示的是文件系统整体情况,不是某个目录自身占用了多少空间。 即使 /var/log 看起来不大,它所在的文件系统也可能被其他目录占满。
2.2 不要忽略 inode
如果应用报告“无法创建文件”,但 df -hT 显示仍有可用容量,还需要检查 inode。
执行:
df -i
或者针对特定路径检查:
df -i /var
-i 表示显示 inode 使用情况,而不是普通的数据块空间使用情况。
inode 用于记录文件系统中与文件有关的元数据。一个文件系统即使仍有大量可用字节空间,也可能因为 inode 耗尽而无法创建更多文件。
这类问题尤其值得关注:
- 应用生成了大量小文件。
- 临时目录积累了大量文件。
- 缓存目录中存在数量庞大的小对象。
- 某些任务不断创建文件,却没有及时清理。
判断原则:
df -hT使用率高:优先排查空间占用。df -i的 inode 使用率高:优先排查文件数量。- 两者都高:可能需要同时处理容量和文件数量问题。
不要因为普通磁盘使用率看起来正常,就跳过 inode 检查。
3. 第二步:用 findmnt 确认真实挂载关系
Linux 文件系统可以挂载到目录树中的不同位置。同一台服务器上的 /、/var 和 /data,可能位于不同的文件系统。
执行:
findmnt --target /var
该命令用于查询指定文件或目录所属的文件系统,并显示对应的挂载信息。findmnt 属于 util-linux 工具集。
如果应用实际把日志写入独立挂载的 /var/log,仅检查根目录 / 的容量就可能得出错误结论。
可以继续执行:
findmnt --target /var/log
df -hT /var/log
这样可以确认 /var/log 对应的文件系统及其使用率。
为什么这一步很重要?
假设一台服务器具有以下目录结构:
/
├── var/
│ └── log/
└── data/
如果 /data 是单独挂载的文件系统,那么 /data 占用大量空间,并不一定会直接导致根文件系统 / 的使用率同步上升。
同样,/var/log 如果独立挂载,其容量问题也应结合该挂载点单独判断。
因此,排查时应把告警中的挂载点、实际写入路径和 findmnt 的查询结果对应起来,避免在错误的文件系统上寻找问题。
4. 第三步:用 du 找出占用空间较多的目录
确定问题文件系统后,再使用 du 分析目录占用。
例如,需要排查 /var 下哪些一级目录比较大,可以执行:
du -xhd1 /var
各参数含义如下:
| 参数 | 含义 |
|---|---|
-x |
不跨越到其他文件系统 |
-h |
使用便于阅读的容量单位 |
-d1 |
只显示目标目录及其下一层目录的统计 |
/var |
本次排查的目标目录 |
GNU Coreutils 官方手册说明,du 用于估算文件和目录的空间使用量;--max-depth 用于限制输出的目录深度,--one-file-system 用于限制跨文件系统的递归统计。
这里的 -d1 是 GNU du 支持的参数写法。如果使用的是 BusyBox 或其他实现,参数可能不同,执行前应核对对应版本的帮助信息。
如何理解输出?
示例输出可能类似:
12M /var/cache
180M /var/lib
24M /var/log
230M /var
以上数字仅用于说明输出格式,不代表任何实际服务器的检测结果。
可以先找出明显占用较多的目录,再继续深入分析。例如,如果 /var/lib 占用较多,可以进一步执行:
du -xhd1 /var/lib
如果 /var/log 是排查目标,则可以执行:
du -xhd1 /var/log
通过逐层缩小范围,可以减少无关目录带来的干扰。
为什么建议使用 -x?
假设 /var 下还挂载了另一个独立文件系统。如果不限制跨文件系统统计,du 可能会继续进入该挂载点,将另一个文件系统中的目录内容也统计进去。
使用 -x 可以让统计范围更贴近当前目标文件系统,降低误判风险。
但需要注意:如果目标目录本身位于一个独立挂载点,du -x 仍会统计该目录所属文件系统中的内容,只是不继续跨入其他文件系统。
空间排查需要注意性能
du 需要遍历目标目录中的文件和子目录。在包含大量文件的目录或繁忙的生产服务器上,扫描可能消耗一定的 I/O 和 CPU 资源。
建议:
- 先使用
df缩小范围。 - 优先检查告警涉及的目录。
- 需要深入扫描时,选择业务低峰期。
- 如果是生产环境,应结合服务器负载和运维规范决定扫描范围。
不要为了快速找到大目录,就直接对整个文件系统执行无范围限制的递归扫描。
5. 进阶:如何定位 inode 占用较多的目录?
如果 df -i 显示 inode 使用率很高,可以使用 GNU du 的 --inodes 选项统计目录涉及的 inode 数量。
例如:
du --inodes -x -d1 /var | sort -n
这里:
--inodes:统计 inode 数量,而不是普通空间使用量。-x:不跨越到其他文件系统。-d1:只显示一层目录统计。sort -n:按数值从小到大排序。
这条命令适用于支持上述选项的 GNU Coreutils 环境。GNU 官方文档明确说明,du --inodes 可以用于查找 inode 消耗较多的目录。
从输出中可以重点关注文件数量明显偏多的目录,再逐层缩小范围。
需要注意,inode 数量多并不必然意味着应用存在故障。缓存、队列、邮件系统和某些业务数据目录,本来就可能包含大量小文件。是否需要清理,应结合业务设计和文件用途判断。
6. 常见问题:为什么 df 和 du 的结果对不上?
这是磁盘排查中经常遇到的情况。
例如:
df -hT /var显示文件系统使用率很高。du -xhd1 /var统计出的目录容量却相对较小。
出现差异不一定意味着命令有问题,常见原因包括以下几种。
6.1 目标目录没有覆盖整个文件系统
du 统计的是指定目录可遍历到的文件和目录。
如果只执行:
du -xhd1 /var/log
那么它只分析 /var/log 这一路径,不会把其他目录的占用算进来。
排查时应确认目标路径与 df 显示的挂载点是否对应。
6.2 文件已删除,但仍被进程打开
在 Linux 中,如果文件名已经被删除,但仍有进程持有该文件的打开文件描述符,那么文件占用的空间可能要等到相关文件描述符关闭后才释放。
这就可能导致:
- 目录中已经看不到该文件。
du无法通过正常的目录遍历统计到它。df仍然显示文件系统存在相应空间占用。
如果已经确认这类情况是排查方向,可以在安装了 lsof 的 Linux 系统上进一步检查:
lsof +L1
lsof 的官方手册说明,+L1 用于选择链接计数小于 1 的已打开文件,也就是常见的已解除链接但仍处于打开状态的文件。
验证边界: 本次测试环境没有安装 lsof,因此上述 lsof +L1 命令未实测。使用前应核对本机 lsof 版本和手册;如果需要查看其他用户进程的文件信息,应遵循授权与最小权限原则。
如果确认某个应用持有已删除的大文件,应先识别进程和文件用途,再依据服务管理规范决定是否重启或重新加载应用。不要仅为了释放空间就随意终止进程。
6.3 文件系统自身的统计口径不同
df 关注文件系统的整体空间统计,而 du 通过遍历文件和目录估算占用量。稀疏文件、文件系统元数据和保留空间等因素,也可能使两者结果不同。GNU du 文档对实际占用空间与文件表观大小的差别进行了说明。
因此,不应要求 df 的已使用空间与某个目录下的 du 结果严格相等。
正确的做法是逐步缩小排查范围,并结合文件系统类型、挂载关系和进程占用信息进行判断。
7. 安全提示:不要一看到磁盘告警就清理文件
磁盘告警发生时,直接执行批量删除命令可能带来更严重的问题。
例如,不应在未确认内容的情况下清空整个日志目录、删除所有临时文件,或对容器资源进行不加区分的批量清理。
建议遵循以下原则:
- 先诊断,再清理。 通过
df、findmnt和du确认真正的问题路径。 - 先识别文件用途。 日志、缓存、数据库文件和业务数据的处理方式不同。
- 确认备份和保留策略。 对重要数据,先确认备份有效且可恢复。
- 遵循最小权限。 普通用户权限足够时,不要为了排查直接使用
sudo。 - 制定回滚方案。 对生产环境的清理操作,应明确执行范围、审批流程和恢复方法。
- 优先使用应用提供的清理机制。 例如日志轮转或应用自身的缓存管理功能,而不是随意删除正在使用的文件。
本文涉及的 df、findmnt 和 du 示例均为只读查询命令,不会主动删除文件或修改挂载配置。但目录扫描仍可能产生一定的系统负载,应根据实际环境控制范围。
8. 总结:按照固定顺序排查更可靠
遇到 Linux 磁盘告警时,可以按照以下流程操作:
第一步:检查空间与 inode。
df -hT
df -i
第二步:确认目标路径对应的文件系统。
findmnt --target /var
df -hT /var
第三步:逐层定位目录占用。
du -xhd1 /var
第四步:如果怀疑 inode 耗尽,再检查目录中的 inode 数量。
du --inodes -x -d1 /var | sort -n
第五步:如果 df 与 du 的结果差异明显,再调查挂载关系、已删除但仍被打开的文件,以及文件系统统计口径。
这套流程的核心不是记住更多 Linux 命令,而是先区分问题类型,再让每一步排查都建立在前一步结果之上。
对于云服务器运维而言,先明确告警对应的文件系统和挂载点,再决定清理策略,比直接删除大文件更加安全,也更容易避免误操作。
- 点赞
- 收藏
- 关注作者
评论(0)