磁盘满的时候别急着删文件,先定位“空间到底被谁占了”。这套流程的核心是:先用 df 确认哪个分区满,再用 du 逐层下钻找到大目录,最后用 find 按大小、时间精准捞出可清理的文件。下面按顺序来。
第一步:df 确认分区,du 逐层下钻
先看整体,别一上来就 du 全盘,那会扫很久。
df -hT
# 找到 Use% 接近 100% 的挂载点,比如 /
du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -20
关键参数:-x 不跨文件系统(避免扫到挂载进来的 /proc、/data 等),--max-depth=1 只看第一层,sort -rh 按人类可读大小倒序。锁定大目录后继续下钻:
du -xh --max-depth=1 /var | sort -rh | head -20
du -xh --max-depth=1 /var/log | sort -rh | head -20
常见元凶:/var/log 下的日志、/var/lib/docker、/home 下的备份包、/tmp 残留。注意 du 统计的是块占用,已删除但仍被进程打开的文件不会出现在 du 里,这种情况看下一步。
第二步:排查“已删除但没释放”的文件
如果 df 显示满、du 加起来却对不上,多半是进程还占着已删除的句柄。用 lsof 找出来:
lsof +L1 2>/dev/null | sort -k7 -rn | head -20
# 或
lsof | grep deleted | awk '{print $7, $2, $9}' | sort -rn | head
确认是哪个服务(比如 nginx、java)后重启它即可释放空间;不能重启的,可以用 : > /proc/<pid>/fd/<fd> 清空文件内容。这一步常被忽略,但往往能立刻救回几个 G。
第三步:find 按大小和时间精准清理
找到大目录后,用 find 列出具体文件,先看再删:
# 找 500M 以上的文件
find /var -xdev -type f -size +500M -exec ls -lh {} ; 2>/dev/null
# 找 30 天前的日志类文件
find /var/log -xdev -type f -name "*.log" -mtime +30 -ls
# 找 7 天未修改的临时文件
find /tmp -xdev -type f -mtime +7 -ls
确认无误后再删,建议先 -print 预览,再加 -delete:
find /var/log -xdev -type f -name "*.log" -mtime +30 -delete
find /tmp -xdev -type f -mtime +7 -delete
几个注意点:-xdev 同样用于不跨挂载点;-size +500M 的 M 必须大写;-mtime +30 表示修改时间超过 30 天。删日志前确认服务是否还在写,最好用 logrotate 做轮转而不是硬删。
第四步:常见清理对象与防复发
- 日志:配置 logrotate,按天轮转并保留 7~14 份,压缩旧日志。
- 包缓存:
yum clean all或apt-get clean。 - Docker:
docker system prune -a清理无用镜像和容器,先确认没有在用的。 - journal 日志:
journalctl --vacuum-size=500M限制总量。 - 大文件误删:先
lsof +L1看句柄,别急着重启机器。
最后提醒:清理前先备份关键配置,删除命令务必先预览再执行。磁盘告警最好配监控(如 df 阈值告警),比事后救火省事得多。


