Appearance
磁盘打满时怎么排查:从 df、du、已删除文件句柄到 Docker 日志
磁盘打满是线上非常经典的一类问题。
它的危险之处在于:
- 表面看只是“空间不够”
- 实际上会连带影响日志写入、数据库、消息落盘和服务稳定性
真正麻烦的点在于,磁盘一满之后很多问题会一起冒出来:
- 日志写不进去
- Docker 容器异常
- 数据库临时文件失败
- MQ、ES、ClickHouse 落盘抖动
- 发布、构建、备份全部受阻
先说结论
遇到磁盘打满,最稳的排查顺序通常是:
text
先看 df -> 再看 du -> 再查已删除未释放文件 -> 再看 Docker/日志/备份目录很多人一上来就开始乱删文件,反而更容易把现场搞乱。
更实用的原则是:
- 先判断满的是哪个文件系统
- 再判断空间被谁占了
- 最后再决定删什么、清什么、是否需要重启进程释放句柄
一、先确认是不是整盘满了
最先看:
df -h
它回答的是:
- 文件系统级别还剩多少空间
这一步非常重要,因为很多人以为“根目录满了”,其实只是:
/var满了- Docker 所在盘满了
- 数据盘满了
- inode 耗尽而不是空间耗尽
如果是 inode 问题,还要看:
df -i
二、再看哪个目录在吃空间
这时看:
du -sh /*- 或逐层往下查
它回答的是:
- 哪个目录真正占得多
更实际的做法通常是逐层缩小:
- 先看一级目录
- 再看可疑目录下的二级、三级目录
最常见的可疑点通常在:
/var/log/var/lib/docker- 备份目录
- 上传导出目录
- 临时目录
三、df 和 du 对不上怎么办
这类场景很经典。
常见原因是:
- 文件已经删了
- 但进程还占着文件句柄
这时要重点查:
lsof | grep deleted
这类问题在线上非常高频,尤其是:
- 应用日志被直接
rm - Docker 日志被直接删除
- 进程还没重启或还没重新打开文件
这时你会看到:
df还是很高du却看不出大文件
如果确认是 deleted 句柄,真正释放空间通常要让持有句柄的进程重新打开文件或退出。
四、最常见的几个根因
1. 应用日志没切割
最常见,尤其是高 QPS 服务和异常风暴时。
2. Docker 容器日志暴涨
这是近几年非常高频的现场来源之一。
3. 备份目录长期不清理
很多备份不是没做,而是“越做越多,没人回收”。
4. 临时文件或导出文件堆积
例如报表导出、离线任务、文件转换、解压目录等。
5. 核心组件自身数据膨胀
例如:
- Elasticsearch 索引
- ClickHouse 数据分区
- MySQL binlog
- RabbitMQ 持久化消息
这类不是简单删日志能解决的,更要看业务和组件本身的保留策略。
五、处理时要注意什么
1. 先止血,再做根因治理
如果已经影响服务,优先清理最安全、最明确的大头目录。
2. 不要一把梭删系统关键目录
尤其不要在没确认用途时直接清理数据库、容器和系统目录。
3. 对日志类问题,补轮转配置比手工删更重要
同理,对备份、Docker 日志、导出文件也要补回收策略,否则很快会再来一次。
六、一个更现场化的排查顺序
如果线上磁盘报警已经打满,我通常会按这个顺序处理:
- 先看
df -h和df -i,确认是空间还是 inode。 - 看哪个文件系统满了,别一开始就在错误目录里排查。
- 用
du逐层找出最大目录和文件。 - 如果
df、du对不上,立刻查 deleted 句柄。 - 再重点看日志、Docker、备份、导出、临时目录和组件数据目录。
- 最后再决定是删文件、轮转日志、回收备份,还是通过进程重启释放空间。
七、处理后别忘了补长期治理
建议至少补:
- 日志切割
- 备份保留策略
- Docker 日志限制
- 磁盘使用监控
如果你的服务器上还跑了数据库、MQ、搜索或分析组件,最好再补:
- 数据保留策略
- 冷热分层或归档策略
- binlog / segment / partition 生命周期管理
一句话总结
磁盘打满这种问题,最怕的不是空间小,而是没有固定排查顺序。
先 df、再 du、再查 deleted 句柄,最后看 Docker、日志、备份和组件数据目录,基本能覆盖大多数真实场景。顺序对了,磁盘问题通常会比想象中更快收敛。