当前位置:首页>Linux>每天学一个Linux命令系列(17):df - 磁盘满了吗?df -h之外你还要知道的事

每天学一个Linux命令系列(17):df - 磁盘满了吗?df -h之外你还要知道的事

  • 2026-09-08 21:24:00
每天学一个Linux命令系列(17):df - 磁盘满了吗?df -h之外你还要知道的事
运
运维少年 · 科技观察

这个命令是干啥的

df 的全称是 disk free(磁盘空闲),用来查看文件系统的磁盘空间占用情况。说人话就是:看磁盘还剩多少空间。

刚学 Linux 的时候,我查磁盘就只会敲 df -h,看一眼有没有满。直到有一次线上告警说"磁盘空间不足",我 df -h 一看还有 20%,心想这不还好好的吗。结果运维老大跑来说:"你看看 inode!"然后我查了 df -i,才发现 inode 已经 100% 了。

从那以后我才知道,磁盘满不只是"空间满了"这一种情况,df 能告诉你的东西远不止这些。

基本用法(3分钟上手)

df:最简陋的查看方式

# 直接敲df,单位是1KB的块
df
# 输出示例(不同系统可能略有差别)
文件系统          1K-块     已用    可用   已用%  挂载点
/dev/vda1       41251136  18936732  20257584   49%  /
tmpfs            1000000       500    999950    1%  /dev/shm

这个单位看着太痛苦,所以基本没人这么用。

df -h:人类友好格式

# 用GB/MB显示
df -h
# 输出示例
文件系统        容量  已用  可用  已用%  挂载点
/dev/vda1        40G   18G   20G   49%    /
tmpfs            977M  512K  977M    1%    /dev/shm

这个命令是我用得最多的,一眼就能看出磁盘还剩多少。

df -h 指定目录

# 查看某个目录所在分区的磁盘情况
df -h /var/log

这个用法特别实用,可以快速确认某个目录落在哪个磁盘分区上。

进阶骚操作

-T:查看文件系统类型

# 加上-T能看到每个分区的文件系统类型(ext4、xfs、tmpfs等)
df -hT
# 输出示例
文件系统       类型     容量  已用  可用  已用%  挂载点
/dev/vda1      ext4      40G   18G   20G   49%    /
tmpfs          tmpfs    977M  512K  977M    1%    /dev/shm

这个参数在迁移数据或排查文件系统相关的 bug 时很好用。有一次我发现一个目录写不进去东西,用 df -T 一看,挂载的是 vfat 格式,不支持 4G 以上的单个文件,破案了。

-i:查看 inode 使用情况

# 查看inode信息
df -i
# 输出示例
文件系统        Inode  已用(I)  可用(I) 已用(I)%  挂载点
/dev/vda1      2621440  2621440       0     100%    /

这个太重要了! 磁盘空间还有,但是 inode 满了,你一样写不了新文件。这种情况常发生在:

1. 有程序疯狂创建超小文件
2. 邮件队列里堆了几十万封未发送邮件
3. 文件系统上缓存了大量临时文件

我记得有一次半夜三点被叫起来,说服务器上 MySQL 写不了数据了。df -h 看空间还有 30%,折腾了半小时没找到原因。最后是群里一个同事提醒:"看看 inode。"我一看,确实 100% 了。最后发现是 /var/spool/postfix/maildrop 下面塞了上百万个邮件文件,用 find 删掉就恢复了。

df vs du 结果不一致

这是个经典问题。有时候 df -h 显示已用了 30G,但用 du -sh /* 加来加去只有 20G。差出来的 10G 去哪了?

常见原因:

# 1. 已删除但进程还在占用的文件
# 用lsof查看哪些进程占用了已删除的文件
lsof | grep deleted
# 2. 文件系统预留块(默认5%)
# 可以用tune2fs查看
tune2fs -l /dev/vda1 | grep "Reserved block count"
# 3. 元数据也占空间
# 格式化的时候就占了一定比例

解决办法一般是重启那个进程(释放文件句柄),或者用 lsof 找到是哪个进程还在吃,然后重启它。

--output 自定义输出列

# 只显示想看的信息列
df --output=source,fstype,size,used,avail,pcent,target -h

这个我平时用得不多,但写脚本的时候很好用,输出格式干净,方便解析。

避坑指南

坑1:100% 不代表真的满了

df 显示的已用百分比是四舍五入的。比如 df -h 显示 / 用了 100%,但 df 看块数可能还有几十 KB。

而且 ext4 默认给 root 预留了 5% 的空间(为了系统关键进程能用),普通用户写到 95% 就写不进去了,但 root 还可以写。

# 查看预留比例
tune2fs -l /dev/vda1 | grep "Reserved"
# 生产环境根分区建议别动预留,但大容量数据盘可以调小
# 比如把5%改成1%
tune2fs -m 1 /dev/vdb1

坑2:文件系统已用 + 可用 != 总容量

# Linux df显示的"已用+可用"通常小于总容量
# 因为系统预留块、元数据也会占空间
# 这是正常的,不用慌

坑3:df 和实际使用量对不上

前面说了,如果删了大文件但进程没重启,空间不会释放。这时候:

# 找出还在占用已删除文件的进程
lsof -nP | grep '(deleted)' | head -10
# 然后重启对应服务
systemctl restart nginx

坑4:NFS 挂载点 df 慢

如果挂载了 NFS 远程目录,df 可能会卡住(因为要去远程服务器查询)。这时候可以加 --direct 参数或者先卸载 NFS。

# 跳过NFS挂载点
df -h --exclude-type=nfs
# 或者只查本地
df -h -l

实战场景

场景1:磁盘告警排查三板斧

线上服务器磁盘告警了,我的排查流程:

# 第一步:看整体情况
df -h
# 第二步:检查inode
df -i
# 第三步:定位大目录
du -sh /* 2>/dev/null | sort -rh | head -10
# 第四步:如果有已删除但未释放的空间
lsof -nP | grep '(deleted)' | grep -v "perf|trace"

场景2:清理 Docker 日志占满磁盘

Docker 容器日志经常把磁盘撑爆:

# 先看看哪个分区满了
df -h /var/lib/docker
# 查看Docker日志占用
du -sh /var/lib/docker/containers/*/*-json.log
# 清空日志(注意是清空不是删除,否则要重启Docker)
truncate -s 0 /var/lib/docker/containers/*/*-json.log

场景3:写监控脚本

#!/bin/bash
# 检查磁盘使用率,超过80%就告警
THRESHOLD=80
df -hP | grep -v "tmpfs" | grep "^/dev/" | while read line; do
    usage=$(echo $line | awk '{print $5}' | cut -d'%' -f1)
    mount=$(echo $line | awk '{print $6}')
    if [ "$usage" -gt "$THRESHOLD" ]; then
        echo "告警:分区 $mount 使用率已达 ${usage}%"
    fi
done

场景4:排查新挂载的磁盘

# 云服务器新挂载了一块数据盘,确认是否已挂载
df -h | grep "/data"
# 没出来?看看磁盘有没有被识别
lsblk
# 如果确认设备存在但没挂载,手动挂载
mount /dev/vdb1 /data
df -h /data

今日作业

请使用 df 命令完成以下任务:

1. 用人类可读的格式查看所有本地文件系统(跳过 tmpfs)的磁盘使用情况
2. 单独查看根目录 / 的 inode 使用率
3. 查看 /var 目录所在的文件系统类型是什么(ext4/xfs/其他)

写出对应的三条命令即可。

E N D

运维少年 · 科技观察

最新文章

随机文章