Ubuntu 服务器磁盘空间异常增长的排查指南

Ubuntu 服务器磁盘空间异常增长的排查指南

Ubuntu Server(尤其是 24.04 LTS / 26.04 LTS)磁盘空间异常增长是生产环境中最常见的告警之一。 异常增长通常不是“突然爆炸”,而是某个子系统持续、隐蔽地积累数据,最终突破阈值。理解背后的机制增长模型,比记住一堆清理命令更重要。

1. 磁盘空间增长的理论模型与常见分类

Linux 文件系统(ext4/xfs/btrfs)空间消耗可以分为三类:

  • 静态消耗:系统、软件包、内核(相对稳定,增长慢)
  • 可预测增长:日志、缓存、临时文件(线性或指数增长,受负载/配置影响)
  • 突发/失控增长:bug、配置错误、恶意行为导致的无限写入(最危险)

2025–2026 年 Ubuntu Server 上最常见的“异常增长源”按频率排序:

  1. systemd-journald 日志(最常见,持久化后特别明显) 默认 volatile(内存),但生产环境几乎都启用 persistent(/var/log/journal)。 无 vacuum 配置时,按大小/时间无限增长,尤其在高负载服务(nginx、mysql、docker)下每天几百 MB 到 GB 级。
  2. Docker / 容器相关(overlay2、container logs、build cache、images) /var/lib/docker 目录下:overlay2(存储层)、containers/*-json.log(无限制日志)、buildkit/tmp、images/prune 未清理。
  3. APT 包缓存(/var/cache/apt/archives) unattended-upgrades 或手动 upgrade 后旧 .deb 未清理,累积几十 GB。
  4. Snap 包(/var/lib/snapd/snaps) Snap 自动保留多个修订版(默认 3–5 个),每个修订版几百 MB 到 GB,更新频繁的应用(如 core、firefox)特别明显。
  5. 应用日志(/var/log/nginx、/var/log/mysql、自定义服务) 无 logrotate 或配置错误(如 debug 级别、无 rotation)导致单个 .log 文件无限增长。
  6. 临时文件 /tmp、/var/tmp 重启不清空、程序异常退出未清理、构建脚本写中间文件。
  7. 旧内核(/boot) 自动更新保留多个内核,占用几百 MB 到 1–2 GB。
  8. 已删除但进程持有的文件(deleted but open) 文件被 rm,但进程仍持有 fd,导致空间未释放(df 显示满,du 显示少)。
  9. inode 耗尽(非空间,而是元数据满) 小文件爆炸(如邮件队列、临时 session 文件),df -i 显示 100%。

2. 分层排查逻辑(从表象到根因)

步骤 1:全局概览(先区分空间 vs inode)

使用 df -hT 和 df -i 同时看。

  • 空间满但 inode 正常 → 大文件在增长
  • inode 满但空间有余 → 海量小文件(常见于 /tmp、/var/spool/postfix、数据库 tmp)

步骤 2:定位占用大户目录(分治法)

从根开始逐级缩小范围。 常见前三名:/var(日志+缓存+docker+数据库)、/home(用户数据)、/usr(snap/flatpak)。

步骤 3:针对性深挖高嫌疑目录

  • /var/log 或 journal journald 持久化后无限制增长是头号嫌疑。 大日志文件往往是循环错误(反复重试、权限问题、debug 模式)导致。
  • /var/lib/docker Docker 默认不限制日志大小、无自动 prune。 build cache、dangling images、dead containers 累积极快。
  • /var/cache/apt 未运行 autoremove/autoclean 时积累旧包。
  • /var/lib/snapd/snaps Snap 修订版保留机制(可配置保留数量)。
  • 已删但未释放 进程持有已删除文件 fd 是“df 满 du 少”的经典原因。

步骤 4:根因分析(为什么会持续增长)

  • 日志类:logrotate 配置缺失/失效、journald 无 vacuum、应用 debug 级别未关。
  • Docker:无 log-opts(max-size)、未定期 prune。
  • Snap:自动刷新 + 高保留数。
  • 临时文件:程序 bug 或 cron 任务异常。

3. 生产环境常见误区与理论陷阱

  • 误区1:只看 du -sh /* 没看到 /var/log/journal → journal 是二进制,不显示在 du 中(需 journalctl –disk-usage)。
  • 误区2:rm 大日志后空间没释放 → 进程仍持有 fd(需重启服务或 kill 进程)。
  • 误区3:清理 /tmp 后又满 → 程序在运行时写临时文件,重启不清空(tmpfs 除外)。
  • 误区4:以为 snap/flatpak 不占空间 → 每个修订版都是完整副本。
  • 陷阱:ext4 默认保留 5% 给 root,df 显示 100% 但 root 还能写(非 root 用户先报错)。

4. 预防与长期治理建议(2026 年视角)

  • journald:配置 Storage=persistent + SystemMaxUse=2G–5G + SystemMaxFileSize=500M
  • Docker:daemon.json 设置 log-driver json-file + max-size: “10m” + max-file: “3”;定期 docker system prune -a –volumes
  • APT:unattended-upgrades + 定期 apt autoremove –purge && apt autoclean
  • Snap:snap set system refresh.retain=2;定期 snap list –all | grep disabled | xargs snap remove
  • logrotate:所有自定义服务强制配置 rotation + compress
  • 监控:Netdata/Prometheus + node_exporter 监控 /var/log/journal 大小、/var/lib/docker 使用率、inode 使用率
  • 告警:磁盘使用 >80%、inode >80%、journal >1G 时告警

磁盘空间异常增长本质上是“某个子系统无限制写入”的表现。 找到持续写入的源头(日志、缓存、容器),理解其增长模型并配置上限/清理策略,是根治的关键。

Telegram