答案是存在已删除但被进程占用的文件、inode耗尽或systemd-journal等du未统计的二进制日志。需依次执行df -i查inode、journalctl --disk-usage看日志占用、lsof +L1找“幽灵文件”,再按风险等级清理。

df -h 显示磁盘已满,但 du -sh /* 加起来远小于 df 报的已用空间?这不是“没空间可清理”,而是你还没看到真正吃空间的地方——比如被进程占用却已删除的文件、日志轮转残留、或 /var/log/journal 这类默认不计入 du 的二进制日志。
Linux 没有内置“自动清理建议”命令,但你可以用一套组合命令快速定位最值得清的几类目标,且每一步都有明确依据。
查完 df -h 后,先看 inode 是否耗尽
磁盘显示 98% 但还能写小文件?可能是 inode 耗尽。运行:df -i
如果某分区的 IUse% 接近 100%,说明大量小文件(如临时 session、缓存碎片、未 rotate 的日志)占满了 inode,du -sh 会低估实际压力。
- 查哪个目录小文件最多:
find /var -xdev -type f | cut -d/ -f 1-3 | sort | uniq -c | sort -n | tail -5 - 常见高 inode 消耗点:
/var/lib/docker/overlay2(容器层)、/var/log/journal(systemd 日志)、/tmp下大量临时文件
journalctl --disk-usage 是最容易被忽略的“隐形大户”
systemd-journald 默认把日志存在 /var/log/journal,是二进制格式,du -sh /var/log 不会包含它(除非加 -xdev 限制跨文件系统)。很多服务器跑几个月后这里就占几个 GB。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 查看真实占用:
journalctl --disk-usage - 安全清理(保留最近 3 天):
journalctl --vacuum-time=3d - 永久限制(写入
/etc/systemd/journald.conf):SystemMaxUse=500M+sudo systemctl restart systemd-journald
对比 df 和 du 差值,找“已删未释放”的文件
执行 lsof +L1(需 root),列出所有被进程打开但 link count 为 0 的文件——也就是你 rm 过但进程还在写的“幽灵文件”。这类文件的空间不会被 du 统计,但 df 会计入。
- 典型场景:Nginx / Apache 正在写一个已被
logrotaterename 并rm的访问日志;Java 应用产生 core dump 后被删但 JVM 还没退出 - 释放方法:重启对应服务,或 kill 对应进程(确认无影响后再操作)
- 验证是否生效:清理后再次
df -h,差值应明显缩小
按风险等级排序清理项,别一上来就 rm -rf /var/cache
不是所有“大目录”都能随便清。优先级取决于是否影响服务稳定性:
- 低风险(可立即执行):
sudo journalctl --vacuum-size=200M、sudo rm -f /tmp/*.tmp、sudo apt clean(Ubuntu)或sudo dnf clean all(RHEL) - 中风险(需确认用途):
/var/log/*.gz(压缩旧日志)、/var/cache/apt/archives/*.deb(已安装包缓存) - 高风险(必须查清再动):
/var/lib/docker(Docker 镜像/容器)、/var/lib/mysql(MySQL 数据目录)、/home/*/.cache(用户级缓存,可能含配置)
真正卡住人的从来不是“找不到大文件”,而是不知道哪些能清、哪些清了会断服务、哪些清了也没用。每次 df -h 报警后,按 df -i → journalctl --disk-usage → lsof +L1 这三步走,90% 的“空间莫名消失”问题就能闭环。剩下的,才是翻 du -sh /* | sort -hr 找目录的事。

















