IT

Linux 磁盘满了别慌:du 和 find 清理实战

AI智能摘要

磁盘告警别急着删文件。先用 df -h 和 df -i 确认哪块盘、是不是 inode 满了,再用 du 逐层钻目录找大户,配合 find 按大小和时间精准捞大文件、旧日志。文中还讲了清空日志的正确姿势,以及删完空间不释放时怎么用 lsof 查句柄。

先定位:到底是哪块盘满了

磁盘告警先别急着删文件,第一步永远是确认哪块分区满了、满到什么程度。用 df -h 看整体,用 df -i 看 inode,这两个都要看——有时候空间还有剩余,但 inode 被小文件耗尽,表现同样是“写不进去”。

df -h
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/vda1        40G   38G  1.2G  97% /
# /dev/vdb1       200G  120G   70G  60% /data

df -i
# Filesystem      Inodes IUsed IFree IUse% Mounted on
# /dev/vda1       2.6M  2.5M  100K   96% /

上例中根分区 97%,inode 也到 96%,说明既要清大文件,也要处理海量小文件。确认目标挂载点后,后续命令都只针对这个目录跑,避免全盘扫描拖慢业务。

du 实战:按目录逐层往下钻

定位到挂载点后,用 du 从根往下逐层找“大户”。关键是加 -x 不跨文件系统、-d 1 只显示一层,先看总量再决定钻哪个目录。

du -xhd1 / 2>/dev/null | sort -rh | head -20
# 15G  /var
# 8.2G /usr
# 3.1G /home
# 1.4G /opt

锁定 /var 后继续钻,一层层缩小范围,直到看见具体文件:

du -xhd1 /var 2>/dev/null | sort -rh | head
# 9.8G /var/log
# 3.2G /var/lib

du -ah /var/log 2>/dev/null | sort -rh | head -10

常见大户是日志、Docker 数据、包缓存、旧内核。清理前务必确认文件用途,/var/log 里的日志优先用 truncate -s 0 清空而不是直接删,避免正在写的进程句柄失效、空间不释放。

# 清空而非删除,进程仍可继续写
: > /var/log/nginx/access.log
# 或
truncate -s 0 /var/log/nginx/error.log

find 实战:按大小、时间、类型精准捞文件

目录里文件太多、du 输出刷屏时,find 更直接。找大于 500M 的大文件:

find / -xdev -type f -size +500M -exec ls -lh {} ; 2>/dev/null | awk '{print $5, $9}'

-xdev 限制不跨挂载点,避免扫到 NFS 或数据盘。找 30 天前的旧日志、临时文件:

find /var/log -type f -name "*.log" -mtime +30
find /tmp -type f -atime +7

确认无误后再加 -delete 或 -exec rm -f,建议先只打印路径核对一遍。清理 inode 占用时,重点找小文件密集的目录:

find /var/spool -xdev -type f | wc -l
du -xhd1 /var/spool | sort -rh | head

收尾:确认空间真的释放了

删完文件 df 没变化,多半是有进程还持有已删除文件的句柄。用 lsof 查 deleted 状态,必要时重启对应服务:

lsof +L1 2>/dev/null | head
# 或
lsof | grep deleted | head

最后再跑一次 df -h 和 df -i 确认。日常建议给日志配 logrotate、给 Docker 设 data-root 和日志上限,从源头减少“磁盘满”复发。

发表评论