一、磁盘空间不足不只一种情况¶
很多人遇到“磁盘满了”时,只会先看 df -h。但实际上,磁盘空间不足至少常见三类原因:
- block 空间真的被大文件占满
- inode 被大量小文件用完
- 文件虽然删除了,但仍被进程占用,空间没有真正释放
先分清是哪一类,再决定怎么处理,排障效率会高很多。
二、block 空间不足:大文件把空间占满¶
2.1 典型现象¶
使用 df -h 查看时,某个分区使用率很高,比如 /boot 达到 93% 甚至更高。
2.2 典型排查思路¶
先看分区空间使用率:
$ df -h
再进入对应目录,用 du -sh 一层层排查具体的大文件或大目录:
$ cd /boot
$ du -sh /boot/*
原始笔记中的示例里,最终定位到 /boot/nginx.log 达到 800M。
确认文件可以删除后,再执行:
$ rm -rf /boot/nginx.log
删除后再次确认:
$ df -h
三、inode 不足:空间还有,但文件建不进去¶
3.1 典型现象¶
有些场景里,df -h 看起来空间还有很多,但创建文件时仍然提示:
No space left on device
这通常意味着 block 没满,但 inode 已经用完。
3.2 典型排查思路¶
先看空间:
$ df -h /app/test
再看 inode:
$ df -i /app/test
如果看到 IUse% 接近或达到 100%,就说明 inode 用尽了。
还可以统计目录下文件数量:
$ ll | wc -l
处理方式通常是删除海量小文件,例如:
$ ls | xargs rm -f
删除后再次确认 inode 使用率:
$ df -i /app/test
四、文件删除了,但空间还是不释放¶
这是 Linux 排障里非常容易踩坑的一类问题。
4.1 文件真正删除需要满足什么条件¶
一个文件彻底释放空间,通常要同时满足两个条件:
- 条件 1:目录项已经被删除,也就是硬链接数归零
- 条件 2:没有进程继续打开这个文件,也就是引用计数归零
所以,哪怕 rm 了文件,只要还有进程在持续占用,空间也不会马上释放。
4.2 用 lsof 观察被打开的文件¶
比如一个终端里执行:
$ tail -f /etc/passwd
另一个终端可以用 lsof 查看文件被谁打开:
$ lsof | grep passwd
常见字段可以简单这样理解:
| 列 | 含义 |
|---|---|
| 第 1 列 | 命令或服务名 |
| 第 2 列 | PID |
| 第 3 列 | 用户 |
| 第 7 列 | 文件大小 |
| 第 8 列 | inode 号 |
| 最后一列 | 文件名 |
4.3 典型故障排查步骤¶
原始笔记的模拟方式是:
1、在 /app/test 里生成一个超大文件 big.log
2、用 tail -f /app/test/big.log 持续占用该文件
3、删除 big.log
4、再次执行 df -h,发现空间并没有回来
这时可以继续排查:
$ lsof | grep delete
如果看到类似:
/app/test/big.log (deleted)
就说明文件路径已经没了,但进程还在占用它。
处理方式通常是结束占用该文件的进程,例如:
$ kill 130624
结束后再看空间,通常就会恢复正常:
$ df -h /app/test
五、三类问题的排查速查表¶
| 故障类型 | 现象 | 排查命令 | 常见处理方式 |
|---|---|---|---|
| block 空间不足 | df -h 显示空间已满 |
df -h、du -sh |
找出大文件,确认后删除 |
| inode 不足 | df -h 还有空间,但无法创建文件 |
df -i、ll | wc -l |
删除海量小文件 |
| 删除未释放 | rm 后空间没回来 |
lsof | grep delete |
结束占用该文件的进程或重启服务 |
六、小结¶
磁盘故障排查最怕“只看一种指标”。实战中建议按下面顺序判断:
1、先看 df -h,确认是不是 block 用满。
2、如果空间看着正常,再看 df -i,确认 inode 是否耗尽。
3、如果文件删了空间还不回收,再用 lsof 检查是否有进程仍在占用。
把这三条思路记住,大部分磁盘空间不足问题都能较快定位。