☰
Linux磁盘管理三剑客:df、du、fdisk命令详解与实战排障
2026/10/22 3:45:09 网站建设 项目流程

1. 三个命令各管一层:磁盘管理到底在管什么

很多人在刚开始玩 Linux 的时候,接触的磁盘命令基本就三个:df、du、fdisk。网上的教程也喜欢把这三个放在一起讲,标题就叫“Linux 命令篇:df、du、fdisk 磁盘管理”。但说真的,如果你只是背会了几个参数,没有理解它们分别站在哪一层看磁盘,遇到真实故障还是会一脸懵。

我先用一句大白话把这三者的关系说清楚:fdisk 是在划分整块硬盘的区域,df 是看操作系统已经格式化好的文件系统还有多少空间,du 是统计目录里那些文件实际占了多少空间。如果你把一个磁盘比作一栋楼,fdisk 就是开发商划户型,df 是物业管理看整栋楼还有多少空房,du 则是你挨家挨户敲门数每户堆了多少东西。

这三者的视角完全不同,但故障场景里又高度耦合。最常见的坑就是:df 显示磁盘满了,但用 du 去一个个目录找,怎么算都对不上,最后排查半天才发现问题根本不在“文件大小”这件事上。所以这篇文章我打算把 df、du、fdisk 分开拆透,然后放在同一个实战场景里串起来讲,帮你把这三个命令真正用到实处。

适合谁来读?刚接触 Linux 服务器的运维新人,或者被“磁盘空间莫名消失”折磨过、想搞清楚 df 和 du 为什么数值不一致的人,这篇文章都能给你一个相对完整的答案。里面没有太多高端操作,都是日常命令,但我保证每一条都是我在真实环境里试过、踩过坑之后才写下来的。

2. df 实操:文件系统视角的空间真相

2.1 df 常用参数解析:-h、-T、-i 组合拳

df 的全称是 disk free,它统计的是文件系统的总空间、已用空间、可用空间和使用率。最常用的无非是加一个 -h 参数,让数字变成人类可读的 G、M 单位。

df -h

输出大概是这样的:

文件系统 容量 已用 可用 已用% 挂载点 /dev/sda3 100G 78G 22G 78% / tmpfs 16G 0 16G 0% /dev/shm /dev/sda1 2.0G 1.1G 820M 58% /boot

这里有个细节容易被忽略:第一行 Filesystem 列里除了 /dev/sda3 这种真实磁盘分区,还有 tmpfs、devtmpfs 之类的伪文件系统。tmpfs 是把一部分内存模拟成磁盘用,所以它的“已用 0%”很正常,不需要紧张。新手如果看到很多挂载点,不要以为系统装了好几个盘。

真正要注意的是 -T 参数,它会显示文件系统类型:

df -hT

你会看到 ext4、xfs、tmpfs、overlay 这些类型。为什么这个信息重要?因为遇到磁盘空间问题,第一步常常要确认你管的到底是哪种文件系统。xfs 和 ext4 的扩容方式完全不同,后面用 fdisk 分区、resize 的时候,文件系统类型不对会直接导致操作失败。

再就是 -i 参数,很多人会漏掉它:

df -i

这个看的是 inode 使用情况。inode 你可以理解为文件系统里用来存文件元数据的“索引卡”,每个文件或目录都要占一个。有时候磁盘空间明明还剩很多,但系统提示无法创建文件,就是 inode 用光了。df -h 看不出任何问题,df -i 一查,已用 100%,真凶立刻现形。

2.2 df 数字背后的隐藏开销:为什么已用空间大于所有文件总和

用 df 看到“已用 78G”之后,很多人会下意识用 du 去统计根目录下所有文件的大小,结果加起来只有 60G,就开始怀疑系统出 bug 了。其实 df 的“已用”本来就不只是用户文件。

第一个隐藏开销是文件系统元数据。ext4 会分配一部分块用来存 inode、块位图、日志(journal)等结构,这些不占用用户可见空间,却实实在在算在 df 的已用里。第二个是保留块,ext 系列文件系统默认预留 5% 给 root 用户,防止系统日志写满时连 root 都进不去。第三个是已删除但没释放的文件。这个最常见也最坑,后面我会在实战章节专门讲。

所以在排查磁盘空间时,df 的数字是“文件系统层面”的真实占用,du 是“目录树层面”的文件大小累加。两者之间有偏差很正常,偏差极大时才需要去查是不是有进程占着已删除文件。

3. du 实操:在目录树里找出空间真凶

3.1 du 常用参数与经典组合:从 5 分钟定位大文件开始

du 的全称是 disk usage,它会递归遍历目录,统计每个文件、每个子目录所占用的块数。最基础也是最实用的命令是看当前目录下每个子目录各占多少:

du -sh *

-s 表示汇总,只显示总计;-h 人类可读。这个命令执行完之后,当前目录下所有子目录和文件的大小一目了然。想往下追查,就进入最大的那个目录重复执行,通常三四层就能找到元凶。

还有一种写法适合深度受限的场景:

du -h --max-depth=1 /var

--max-depth=1 意思是只统计到第一层子目录,不会递归到底。日志目录这种层级深、文件多的地方,用这个参数比 du -sh * 更清晰,因为你直接看到了 /var/log、/var/lib、/var/cache 各自的体积对比。

再补充一个生产环境常用的:

du -sh /var/log/* | sort -rh | head -20

sort -rh 按人类可读数字反向排序,head 取前 20 行。这个组合我几乎每次排查空间问题都用,比一条条 du 看过去快得多。

还有一个 -x 参数值得记住:du -x 表示不跨越文件系统边界。比如你 du -sh /,它会自动跳过其它挂载点,只统计根所在文件系统的内容。这样避免你把一个挂载在 /data 的独立磁盘也递归进去,统计结果更干净。

3.2 为什么 du 统计出来和 df 对不上:三种典型原因

先说结论,du 和 df 对不上不代表系统异常,但差距太大就要警惕。第一种原因是已经删除但进程还在写的文件。你删除了一个正在被程序打开的日志文件,文件系统立刻释放了空间,但进程的文件句柄还指向这个文件,操作系统为了保证程序不崩溃,会把文件内容保留到进程关闭为止。df 看到的已用包含了这部分,du 遍历目录数不到它,于是出现 df 显示满了、du 怎么找都找不到大文件的诡异现象。

排查方法用 lsof:

lsof | grep deleted

找到被删除但未释放的文件后,重启对应进程或者 kill 掉占用进程,空间就会真正释放。注意不能直接拿 du 去删文件,因为你根本看不见它。

第二种原因是挂载点边界。如果 /var/log 是一个独立分区,你在根目录执行 du -sh *,看到的是 /var 目录下所有内容的总和,但 du 的统计会递归进入 /var/log 这个挂载点对应的文件系统里,把不属于根分区的空间也算了进去。所以跨分区统计时必须清醒,加 -x 或者单独统计才能准确。

第三种原因是稀疏文件和文件系统块粒度。文件系统最少分配一个块(通常 4KB),一个只有 1 字节的文件也占 4KB,大量小文件会让 du 统计的“文件大小”和实际占用的块数不一致。du 默认按块统计,这个偏差不会特别大,但小文件多时确实存在。

4. fdisk 实操:磁盘分区完整流程与避坑经验

4.1 fdisk 操作前的识别与备份:先看清设备名再动手

fdisk 是传统的磁盘分区工具,操作对象是整块磁盘,比如 /dev/sdb,不是 /dev/sdb1。这一步搞错,轻则误删分区,重则把系统盘搞挂。我第一次给服务器加磁盘时差点在 sda 上执行分区,还好敲 w 之前看了一眼提示,冷汗都下来了。

操作前先列出所有磁盘:

fdisk -l lsblk

lsblk 的输出更直观,能看到设备层级关系。比如 sda 下面有 sda1、sda2,说明这块盘已经被分过区。新加的空盘 sdb 下面没有任何子设备,才适合做分区操作。

如果要对已有分区表做修改,先备份:

sfdisk -d /dev/sdb > sdb_part_backup.txt

这个命令把整个分区表导出成文本,万一改崩了可以用下面命令恢复:

sfdisk /dev/sdb < sdb_part_backup.txt

备份脚本我都是直接放到一个固定的备份目录里,命名带日期和主机标识,以防真的需要恢复时找不到文件。

4.2 新磁盘分区完整过程:从 fdisk 到 mount 一次性学会

假设系统里加了一块新盘 /dev/sdb,我们要分一个主分区,格式化成 ext4,然后挂载到 /data。

第一步,进入交互式分区界面:

fdisk /dev/sdb

输入 n 创建新分区,fdisk 会让你选择分区类型,p 表示主分区。如果磁盘已经存在扩展分区,fdisk 会提示你是不是要创建逻辑分区,这在 MBR 时代很常见,现代直接用 GPT 的话基本不需要扩展分区这个概念。

接着选择分区编号,默认 1 即可。起始扇区直接回车用默认值,结束扇区如果你想把整个磁盘都分给这个分区,直接回车,或者输入 +50G 指定大小。

然后输入 w 保存并退出。注意,在输入 w 之前,所有修改都只存在于内存里,磁盘上的分区表并没有变化。如果把设置搞错了,直接输入 q 退出,不会对磁盘造成任何影响。这个 w 和 q 的区别,可以说是新手最容易忽略的分区安全闸门。

分区完成后,让内核重新读取分区表:

partprobe /dev/sdb

如果不执行这一步,系统可能还看不到新分区 sdb1,需要重启才能识别。partprobe 就是用来避免重启的。

接下来格式化文件系统:

mkfs.ext4 /dev/sdb1

格式化是破坏性操作,执行前 fdisk -l 再确认一次设备名,这个步骤写成习惯后能救你很多次。

然后创建挂载点并挂载:

mkdir -p /data mount /dev/sdb1 /data

最后写入 /etc/fstab,实现开机自动挂载。这里千万别直接写 /dev/sdb1,因为设备名可能漂移,比如拔掉一块盘后 sdb 变成 sdc。用 UUID 更稳定:

blkid /dev/sdb1 vim /etc/fstab

在 fstab 里加一行:

UUID=xxxx-xxxx-xxxx /data ext4 defaults 0 2

写完可以执行 mount -a 测试配置是否正确,如果报错就说明 fstab 写的有问题,赶紧修正,免得下次重启进不了系统。

4.3 GPT 与 MBR 的选择:新版 fdisk 比你想象的更强大

很多老教程会说 fdisk 只支持 MBR,GPT 分区要用 gdisk。这个说法已经过时了,新版 util-linux 的 fdisk 已经原生支持 GPT。我可以直接在 fdisk 交互界面输入 g 创建新的 GPT 分区表,输入 o 创建 MBR 分区表。

为什么推荐 GPT?MBR 分区表对块设备大小有限制,超过 2TB 的盘用 MBR 只能识别出 2TB,剩余空间全浪费。GPT 没有这个限制,而且支持的分区数量远超 MBR 的 4 个主分区限制。现在新买的服务器硬盘动辄几 T,我基本全用 GPT。

如果遇到旧系统兼容性问题,可以用 fdisk -l 查看磁盘当前的 partition table type。需要转换为 GPT 时,先备份数据,再执行 fdisk /dev/sdb,输入 g 创建新分区表。这个操作会把整块盘原来的分区表清空,所以务必先备份分区表再操作。

5. 组合实战:日志服务器磁盘报警排查全过程

5.1 现象:df 显示已用 98%,du 却找不到大文件

有一次我收到告警,某台日志采集服务器的根分区使用率到了 98%。这台服务器只跑了一个日志转发进程,按理说不该有什么大文件。我先执行 df -h,看到 /dev/sda2 已用 98%,然后 du -sh /* 挨个查,发现 /usr、/var、/home 加起来才占 60% 左右,怎么都对不上。

这种场景非常有代表性:df 说满了,du 却找不到占空间的目录。如果你也遇到这种情况,不要怀疑 du 统计错误,应该优先考虑是不是有进程占用了已删除的文件。

5.2 排查三步:lsof 定位句柄、重启进程、验证空间

第一步,看哪些进程占着已删除的文件:

lsof | grep deleted

输出里能看到类似:

log_forward 12345 root 7w REG 8,2 1024000000 123456 /var/log/app.log (deleted)

这说明 PID 12345 的进程打开了一个已经删除的日志文件,文件大小 1GB 左右,文件占用的空间不会释放。

第二步,重启或杀掉对应进程,让系统回收空间。如果这个进程是关键服务,最好走正常重启流程,直接 kill 可能引发服务中断。

第三步,再执行 df -h 确认空间已释放。实测下来,进程重启的一瞬间,df 的已用就断崖式下降。这个操作我做过很多次,每次都有一种“磁盘空间凭空回来了”的奇妙感,其实原理很简单,文件被进程持有,所以文件系统不敢释放。

顺便提一个防止这个问题反复出现的办法:日志文件用 logrotate 切割后,程序必须重新打开新日志文件,否则旧文件一直被占用。配置 logrotate 的 copytruncate 选项可以缓解这种情况,但终极方案还是让应用配合 reopen 信号。

5.3 顺便用 fdisk 勘察磁盘布局

排查完空间问题,我习惯顺手用 fdisk -l 看一眼磁盘布局,确认根分区没有跨盘异常,新加的盘是否还有可分配空间。比如这台服务器有一块 500G 的数据盘,但只分了一个 200G 分区,剩下 300G 处于未分配状态。这个信息放在平时可能无所谓,但磁盘容量紧张时,提前知道可扩展空间有多大,能帮助你快速决定是扩展分区还是增加新盘。

在这个场景里,df、du、fdisk 三个命令刚好形成一条完整链路:df 发现异常,du 缩小范围,fdisk 了解底层可调整的资源。单独会其中一个都不够,串联起来才算真正的磁盘排查。

6. 常见问题与排查技巧实录

6.1 高频故障:空间满了、inode 满了、分区表错了

我把日常最容易遇到的问题整理成一个速查表,方便你收藏备用。

故障现象排查命令常见原因解决思路
df 显示已用 100%du -sh * 找大目录日志膨胀、大文件堆积清理或迁移文件,配置 logrotate
df 空间正常但建不了文件df -iinode 耗尽删除海量小文件,或重建文件系统
df 和 du 统计对不上lsof | grep deleted进程占用已删除文件重启进程释放句柄
新增磁盘系统不识别fdisk -l、lsblk驱动未加载或没分区检查驱动、用 fdisk/gdisk 分区
fstab 写错开机卡住mount -a 提前验证UUID 或挂载点写错进入单用户模式修正 fstab

这里的核心排查思路是:先用 df 确定大方向,再用 du 定位文件,最后用 lsof 和 fdisk 解决底层问题。顺序不要乱,乱了容易绕远路。

6.2 独家避坑经验:三个命令操作习惯必须养成

第一个习惯,fdisk 里输入 w 之前,永远先确认自己在哪块盘上。fdisk 交互界面虽然会显示当前操作的设备名,但实际操作时,习惯性看 fdisk -l 的返回,对照容量和型号,再动手分区。

第二个习惯,生产环境改分区前,务必备份分区表。sfdisk -d 一条命令就能完成,成本极低,但真出问题时能救命。我见过因为改动分区表把一块有数据的盘搞成空盘的情况,幸好有备份,几秒钟就恢复了。

第三个习惯,不要在生产环境直接df -h看了一眼就下结论。df 的输出受挂载点、文件系统类型影响很大,最好配合 mount、lsblk 一起查看当前挂载结构,搞清楚哪些是伪文件系统、哪些是独立分区,再做判断。

6.3 小技巧:du 与 find 搭配精准清理过时文件

如果你定位到某个目录占了几十 G,想快速找出里面最老的文件,可以用:

find /var/log -type f -mtime +30 -size +100M -exec ls -lh {} \;

这条命令筛选出超过 30 天没改过、大小超过 100M 的文件。在清理之前,先看一眼输出,确认这些文件确实没有保留价值,再决定是直接删除还是归档。删除动作要谨慎,特别是日志文件,有些可能涉及合规要求,需要先确认公司相关政策。

我个人在实际操作中的体会是,磁盘管理这几个命令本身不难,难的是理解每一层视角的差异。df 看到的是文件系统,du 看到的是文件,fdisk 看到的是磁盘。把这三层关系在脑子里理清楚后,很多看似诡异的问题都会变得很简单——无非是某个进程占着空间不放手,或者某块盘的容量规划没做好。最后再送大家一个小建议:新机器到手,先把 lsblk、df -hT、df -i 三个命令的输出截图或记录下来存档,以后排查问题时有个基准线可以参考,比临时猜测靠谱得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询