IT

Linux 服务器磁盘满了怎么清理:du 与 find 实战排查思路

AI智能摘要

磁盘满了先别乱删。先用 df 看哪个分区满,再用 du -x 逐层下钻找大目录,遇到 df 和 du 对不上就查 lsof 里已删除但被占用的文件。最后用 find 按大小、修改时间精准清理日志和临时文件,顺手把 logrotate、包缓存、Docker 垃圾一起收拾掉。

磁盘满的时候别急着删文件,先定位“空间到底被谁占了”。这套流程的核心是:先用 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 阈值告警),比事后救火省事得多。

发表评论