这是典型的“已删除但未释放文件”问题:进程仍占用已被rm删除的文件句柄,导致df显示满而du统计小;可用lsof +L1或lsof|grep deleted定位,重启进程或kill释放,禁用echo>/proc//fd/清空。

df 显示磁盘已满,但 du 统计总和远小于该值
这是典型的“已删除但未释放文件”问题:某个进程仍在占用已被 rm 删除的文件句柄,导致磁盘空间无法回收。
执行 lsof +L1 可列出所有被删除但仍被打开的文件(+L1 表示 link count = 0);若无输出,尝试 lsof | grep deleted(部分旧版 lsof 不支持 +L1)。
常见场景包括:日志轮转后旧进程未重载、容器内应用未响应 SIGUSR1、长时间运行的 tail -f 指向已被删的日志。
- 确认后,可选择重启对应进程(如
systemctl restart nginx),或直接 kill 进程(kill -9)强制释放 - 不建议用
echo > /proc/清空文件内容——可能破坏进程逻辑,且对只读 fd 无效/fd/ - 若为容器环境,需进入容器命名空间排查:
nsenter -t,再查-m -u -i -n -p -- /bin/sh /proc/self/fd/
快速定位大目录:du 和 ncdu 的取舍
du -sh /* 2>/dev/null | sort -hr 是最轻量的顶层扫描方式,但会跳过权限不足目录(如 /root、/var/lib/lxc)。
若需深度扫描且机器有交互终端,优先用 ncdu:ncdu / 支持键盘导航、实时排序、按 d 安全删除,比纯 du 更直观。
- 无 ncdu 时,可用
du -h --max-depth=1 /var 2>/dev/null | sort -hr逐级下钻,避免一次性扫全盘耗时过长 - 注意
du默认统计逻辑大小,对稀疏文件(如 qcow2 镜像)可能严重低估实际占用,此时应加--apparent-size对比 - 别在
/proc、/sys、/dev上跑du——这些是虚拟文件系统,du会卡住或报错
清理 /var/log 下的 journald 日志
systemd-journald 默认不限制日志体积,长期运行的服务器可能积累数十 GB 的 /var/log/journal/ 数据。
先查当前用量:journalctl --disk-usage;再按需清理:
- 保留最近 3 天:
journalctl --vacuum-time=3d - 限制总大小为 500M:
journalctl --vacuum-size=500M - 永久生效:编辑
/etc/systemd/journald.conf,取消注释并修改SystemMaxUse=500M和MaxRetentionSec=1month - 注意:设太小会导致
journalctl -u sshd查不到历史记录;生产环境建议至少留 100M
临时腾空间:用 truncate 清空正在写入的大文件
当发现某个正在被追加的日志(如 /var/log/syslog 或应用自定义 log)占满磁盘,又不能停服务时,truncate 是最安全的清空手段。
与 > file 或 echo "" > file 不同,truncate -s 0 file 不改变 inode、不中断写入流,进程仍可继续写入。
- 务必确认目标文件确实在被持续写入(
lsof +L1 | grep file或ls -l /proc/*/fd/ | grep file) - 禁止对数据库数据文件、qcow2 镜像、二进制可执行文件使用
truncate——会直接损坏数据 - 操作前建议先备份 inode:
ls -i /path/to/file,清空后检查是否仍是同一 inode,确保没被重建
真正棘手的情况往往不是空间不够,而是清理后空间立刻又被填满——这说明有异常写入源(如无限循环日志、coredump 未关闭、监控 agent 本地缓存暴增)。这时候得盯住 inotifywait -m -e create,modify /var/log 或 fatrace 实时抓写入行为。










