磁盘显示有空间却报“磁盘已满”,实因三类隐性占用:已删除但进程仍打开的文件、inode 耗尽、Docker 日志或镜像持续写入;需用 df -h、df -i、lsof +L1、du 等组合定位真凶,再分场景精准清理。

为什么 df 显示还有空间,却总报“磁盘已满”?
这不是误报,而是 Linux 存储机制在“说实话”:空间可能被三类东西悄悄吃掉——已删除但进程仍打开的文件、大量小文件耗尽 inode、Docker 镜像层或容器日志持续写入却不清理。比如 lsof +L1 一查,常发现 Java 或 Nginx 进程还占着 /var/log/app.log (deleted) 的句柄,删了也白删;又或者 df -i 显示 inode 使用率 99%,但 df -h 才用 60%,这时新建任何文件都会失败。
别急着删,先用这组命令锁定真凶路径
盲目 rm -rf 可能干掉正在写日志的服务或数据库临时文件。优先执行:
-
df -h看哪个挂载点爆了(重点关注/、/var、/home) -
du -sh /* 2>/dev/null | sort -hr | head -10快速定位根下前 10 大目录 - 进可疑目录后,比如
/var,再跑du -sh * | sort -hr | head -5 - 对运行中服务,必须补上
sudo lsof +L1 | grep deleted,确认有没有“幽灵文件”
特别注意:find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null 能揪出隐藏大文件,但别直接加 -delete——很多 core.* 或 dump 文件需先确认归属进程再处理。
清理要分场景,不能一刀切
系统日志、应用日志、Docker 缓存、临时文件,每类清理逻辑完全不同:
-
journalctl --disk-usage查 systemd 日志占用;用journalctl --vacuum-size=200M收缩,别碰/var/log/journal目录本身 - Nginx/MySQL/Tomcat 日志,检查是否启用
logrotate;没配就补/etc/logrotate.d/nginx,务必加copytruncate防服务中断 - Docker 主机必跑
docker system prune -f,但得提前确认无重要停止容器;/var/lib/docker/tmp也要定期清 -
/tmp可清,但先lsof +D /tmp看有没有进程正用着里面文件
一个典型坑是:apt clean 或 yum clean all 只清包缓存,不碰 /var/cache/apt/archives/partial/ 下的下载中断残留,得手动 rm -rf /var/cache/apt/archives/partial/*。
告警变“稀客”,关键在关住水龙头
反复清理只是擦水渍,真正要盯的是增长源。比如某台机器 /var/log 每周涨 2.3GB,就得查是不是某个脚本每小时 dump 一次全量日志;又比如 Docker 容器日志没限流,--log-opt max-size=10m --log-opt max-file=3 这种配置必须写进 docker run 或 compose.yml。阈值也不能死卡 90%,Zabbix/Prometheus 建议设阶梯告警:85% 邮件、92% 企微、95% 自动触发归档脚本——而脚本里该压缩的压缩,该通知的通知,不该删的绝不删。










