Linux 磁盘空间告急时的应急处理策略

11次阅读

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

Linux 磁盘空间告急时的应急处理策略

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)。

若需深度扫描且机器有交互终端,优先用 ncduncdu / 支持键盘导航、实时排序、按 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=500MMaxRetentionSec=1month
  • 注意:设太小会导致 journalctl -u sshd 查不到历史记录;生产环境建议至少留 100M

临时腾空间:用 truncate 清空正在写入的大文件

当发现某个正在被追加的日志(如 /var/log/syslog 或应用自定义 log)占满磁盘,又不能停服务时,truncate 是最安全的清空手段。

> fileecho "" > file 不同,truncate -s 0 file 不改变 inode、不中断写入流,进程仍可继续写入。

  • 务必确认目标文件确实在被持续写入(lsof +L1 | grep filels -l /proc/*/fd/ | grep file
  • 禁止对数据库数据文件、qcow2 镜像、二进制可执行文件使用 truncate——会直接损坏数据
  • 操作前建议先备份 inodels -i /path/to/file,清空后检查是否仍是同一 inode,确保没被重建

真正棘手的情况往往不是空间不够,而是清理后空间立刻又被填满——这说明有异常写入源(如无限循环日志、coredump 未关闭、监控 agent 本地缓存暴增)。这时候得盯住 inotifywait -m -e create,modify /var/logfatrace 实时抓写入行为。

text=ZqhQzanResources