磁盘满了怎么查:从 df 到 du,再到那个删了也不释放的文件
服务器突然写不进文件,日志停了,数据库报错。第一反应都是敲 df -h,看到某个分区 100%,然后开始删日志。
但有一类情况会让人卡很久:df 说满了,du 加起来却只有一半。
这篇把磁盘占用的排查拆成四级,从粗到细,最后一级是最容易漏的。
第一级:看分区,确认是哪个盘满了
df -h
输出里的 Use% 是判断依据。注意两点:
一是看清楚挂载点。很多人在根分区上删了半天,实际满的是 /var 或 /data 这种独立挂载的分区。
二是注意 inode。有些文件系统会因为 inode 耗尽而无法创建新文件,但空间还有富余:
df -i
如果 IUse% 是 100% 而空间没满,那就是小文件太多——常见于缓存目录、session 文件、邮件队列。这种情况删大文件没用,得删大量小文件。
第二级:找大目录,缩小范围
du -h --max-depth=1 / 2>/dev/null | sort -rh | head -20
--max-depth=1 只看第一层,sort -rh 按人类可读的大小倒排。这样能快速定位到是哪个顶层目录在膨胀。
确定了大方向后再往下钻:
du -h --max-depth=2 /var | sort -rh | head -20
一层层往下,通常三五轮就能定位到具体目录。
注意 2>/dev/null:不加这个会刷出一堆权限不足的报错,把有用信息淹掉。
第三级:找大文件
定位到目录后,直接按大小排序找文件:
find /var/log -type f -size +100M -exec ls -lh {} \; | sort -k5 -rh | head -20
或者用 du 加排序:
du -ah /var/log | sort -rh | head -20
日志是最常见的大头。如果发现某个日志文件已经几个 G,别急着 rm——正在写的日志文件被删掉,句柄还开着,空间不会释放(这就是第四级要讲的)。
正确做法是清空内容而不是删除文件:
: > /var/log/某个应用.log
或者用 truncate:
truncate -s 0 /var/log/某个应用.log
这样文件还在,写入方不受影响,空间立刻释放。
第四级:df 和 du 对不上的时候
这是最经典、也最容易卡住人的情况:
df -h # 显示 / 已用 100%
du -sh /* # 加起来只有 50%
差了将近一半。原因是:有文件已经被删除了,但仍然被某个进程打开着。
Linux 的规则是:文件被 unlink(删除目录项)后,如果没有进程持有它的句柄,空间才真正释放。如果有进程还开着这个文件(比如一个不停写日志的服务,日志文件被 rm 掉了),那块空间就一直被占着,du 看不到它(因为它已经没有目录项了),但 df 会算进去。
怎么找出来
lsof +L1
+L1 的意思是"列出 link count 小于 1 的文件"——也就是已经被删除、但还有进程开着的文件。
如果机器上没装 lsof,可以直接翻 /proc:
ls -l /proc/*/fd/* 2>/dev/null | grep deleted
输出里会显示类似 ... -> /var/log/app.log (deleted),前面是进程 pid 和文件描述符编号。
怎么解决
找到进程 pid 后,有几种处理方式,按安全程度排序:
最安全:重启那个服务。 进程重启后句柄释放,空间自动回来。
次安全:只让进程重新打开日志文件。 很多服务支持信号通知:
kill -USR1 <pid>
不少守护进程收到 USR1 会重新打开日志文件(logrotate 就是这么工作的)。但不同程序行为不同,用之前查一下它的文档。
最后手段:kill -9。 会丢数据,除非确认那是个可以随便杀的东西。
千万别做的:手动去 /proc/<pid>/fd/<n> 上做 truncate。这个操作在某些内核版本上行为诡异,可能把文件指针搞乱,导致进程后续写入错位。真要用也得先停服务。
一个预防习惯
排查完把根因修掉,否则下周还会来一次:
- 日志不轮转 → 配
logrotate,按大小或日期切分并保留 N 份 - 临时文件堆积 → 加一条定时清理,注意排除正在使用的
- 容器日志无限增长 → 给 docker 配
max-size和max-file,否则/var/lib/docker会把盘吃干净 - 数据库 binlog 不清理 → 设置保留天数
小结
排查顺序记成一句话:df 找分区 → du 找目录 → find 找文件 → lsof +L1 找幽灵。
最后一级是分水岭。会用 lsof +L1 的人,遇到"删了不释放"能十分钟解决;不会的人,可能会重启整台机器,甚至以为磁盘坏了。
一个提醒:排查期间不要急着 rm。先看清楚谁占着、为什么占着,再动手。删文件是最简单的一步,也最容易白删。
- 点赞
- 收藏
- 关注作者
评论(0)