Linux 磁盘空间排查入门:df 与 du 怎么用
在 Linux 服务器上,磁盘满了很少会提前打招呼。常见的表现是:网站突然打不开、文件上传失败、数据库写入报错、服务重启后起不来,或者日志里出现 No space left on device。遇到这些现象,先不要急着删东西。正确的顺序是:先用 df 看是哪个分区满了,再用 du 找出是哪个目录在长大,最后确认文件能不能删、删了会不会影响正在运行的服务。把这个顺序记下来,大多数磁盘问题都能在十分钟内定位。
一、先看全局:df 是看分区的
df 的意思是 disk free,它回答的是每个已挂载分区还剩多少空间。最常用的是:
df -h
df -hT
df -i
-h 会用人能读懂的单位显示,比如 20G、850M,而不是一长串字节数。-T 会同时显示文件系统类型,例如 ext4、xfs。-i 看的是 inode 使用率,这一点新手最容易忽略:有时候空间明明还有,但小文件太多把 inode 用完了,同样写不进新文件。
看 df -h 的输出时,重点看四列:Used 是已用,Avail 是可用,Use% 是使用率,Mounted on 是挂载点。举个例子,如果根分区 / 的 Use% 是 92%,而 /data 只有 30%,那问题就在根分区里,而不是数据盘。反过来,如果网站数据都在 /data 上,根分区满了也不一定是网站文件造成的,可能是日志或者临时文件占了根分区。
另外,输出里常见的 tmpfs、overlay、/dev/shm 一般是内存文件系统或者容器相关的挂载点,不用一看到名字就紧张。先锁定 Use% 高、并且确实对应业务数据的那个挂载点,再往下查。
二、再定位:du 是找目录的
确定分区之后,用 du 找这个分区里最大的目录。du 的意思是 disk usage,它会沿着目录往下算,告诉你每个目录实际占了多少。
du -sh /*
du -sh /var/*
du -h --max-depth=1 /var/log | sort -hr | head -20
-s 是只显示汇总,不把每个子目录都列出来;-h 同样是人性化单位。--max-depth=1 表示只看一层深度,配合 sort -hr 按大小倒序、head -20 只看前 20 个,这样一眼就能看到最大的几个目录。
一个实用的排查节奏是:先 du -sh /* 看根目录下一级谁最大,假设是 /var 最大,再 du -sh /var/*,假设是 /var/log 最大,再继续往里一层一层走。每走一层,范围就缩小一圈,比一开始就全盘扫描快得多,也更不容易被海量小文件拖慢。
三、df 和 du 结果不一样怎么办
新手常问:为什么 df 说分区满了,du 加起来却没那么多?最常见的原因是文件已经被删除,但还被某个进程打开着。这种文件在目录里已经看不见了,du 算不到它,可是文件系统仍然为它保留着空间,直到进程退出或者服务重启,空间才会真正释放。
这时可以用下面这条命令找被删除但仍被占用的文件:
lsof | grep deleted
如果输出里有很大的日志文件,并且对应的是某个应用进程,先不要直接杀进程。正确做法是:确认这个服务能不能重启,或者先把它的日志输出停掉、做一次日志轮转,再重启对应服务。重启后一般再跑一次 df -h,空间就会回来。
另一个常见原因是挂载点被遮住了:比如先往 /data 里写了文件,后来又把另一个磁盘挂载到 /data 上,原来的文件就被新挂载点盖住了,du 在新挂载点下看不到它们,但 df 统计的还是底层分区的空间。遇到这种情况,先检查挂载关系,再决定是卸载后清理,还是直接扩容。
四、能删什么、不能删什么
定位到大目录之后,清理也要分清楚。相对安全的通常是:已经轮转过的旧日志、明确过期的备份副本、应用产生的临时缓存、下载目录里不再需要的安装包。清理之前,先用 du -sh 再确认一次目录大小,并且确认这个目录不是数据库的数据目录,也不是正在运行的应用的工作目录。
千万不要做的事包括:用 rm -rf / 或者通配符乱删根目录下的文件;把 /boot 里的内核全部删掉;直接删除数据库的数据文件;删除正在写入的大日志文件本身而不是做轮转。删错数据文件的代价,远比磁盘满本身大得多。
清理完之后,一定要复查:
df -h
如果 Use% 下降了,说明清理有效;如果没变化,再回头看是不是被删除未释放、或者挂载点遮挡的问题。不要只凭感觉说已经清理完了。
五、给新手的排查清单
- 先跑
df -h,确定是哪个分区满了,Use% 是多少。 - 再跑
df -i,排除 inode 用完的情况。 - 用
du -sh一层一层往下走,找到最大的目录。 - 判断这个目录里最大的是日志、备份、缓存还是业务数据。
- 只清理可再生、可重建的文件,关键数据先备份再动。
- 清理后跑
df -h复查;空间没释放就查lsof | grep deleted。
六、常见坑
第一,只看根分区。很多服务器把 /var、/data、/home 分开挂载,根分区满和数据盘满完全是两回事,一定要看 Mounted on 那一列。第二,把 /proc、/sys 当成真磁盘,这两个是内核提供的虚拟文件系统,大小不用按普通目录理解。第三,du 扫大目录很慢,可以用 --exclude 排除不需要的目录,或者先限定到可疑目录再展开。第四,磁盘满了之后,应用可能连日志都写不进去,报错信息本身就不完整,这时更要先用 df 确认,而不是只盯着应用日志猜。
记住一句口诀:df 看分区,du 找目录,先定位、再确认、最后清理。养成定期看一眼 df -h 的习惯,设置一个 80% 左右的提醒阈值,很多磁盘满的问题在变成故障之前就能被发现。
- 点赞
- 收藏
- 关注作者
评论(0)