服务器根分区 84%:一次相对稳妥的磁盘清理流程

踩坑实录 2026-06-25 60
预计阅读时间:8 分钟

穷人才知道的多,富人不需要知道那么多,扩容、加硬盘就完了(狗头)

这次服务器根分区 /dev/vda2 只有 40GB,已经用了 32GB,使用率到了 84%。这个状态要及时处理。系统盘一旦写满,后面的问题会很直接:数据库写不进去,日志无法记录,容器启动失败,应用也可能异常退出。

存储空间占用

所以这次清理的思路不是上来就删文件,而是三步:先定位,再清理,最后防止它继续涨。

第一步:先找出空间被谁占了

先看根目录下各目录的占用:

sudo du -xhd1 / 2>/dev/null | sort -hr

实际占用大小

这里建议加 -x,避免 du 跨文件系统统计,导致结果和 df -h / 对不上。比如根分区只有 40GB,但 /var/lib 显示 47GB,就要怀疑是不是统计到了其他挂载点。

如果发现 /var 很大,继续往下看:

sudo du -xhd1 /var 2>/dev/null | sort -hr

常见大户一般有几个:/var/lib/docker/var/log、应用日志目录、临时文件目录和旧备份文件。我这次主要是 Docker 占用,清理后释放了十几 GB。

第二步:先做低风险清理

APT 缓存可以先清:

sudo apt clean
sudo apt autoremove

系统日志也可以检查,但不要一上来就删:

sudo du -sh /var/log/*

如果是 journald 占用较大,可以按时间清理:

sudo journalctl --disk-usage
sudo journalctl --vacuum-time=7d

如果确认某些传统日志文件过大,可以用 truncate 清空,而不是删除正在被服务写入的日志文件:

sudo truncate -s 0 /var/log/syslog
sudo truncate -s 0 /var/log/kern.log

注意,日志清空后,排查线索也会消失。更稳的做法是先确认日志内容是否还需要保留,再清理。

第三步:重点清理 Docker

先看 Docker 到底用了多少空间:

docker system df

如果镜像、停止容器、构建缓存占用明显,可以先执行:

docker system prune -af
docker builder prune -af

docker system prune -af 会清理停止的容器、无用网络、构建缓存和未被容器使用的镜像。它通常是第一轮比较有效的清理方式。

但不要随手加 --volumes

卷和镜像不一样。Volume 里可能是数据库、上传文件、应用持久化数据。即使某个卷当前没有被容器使用,也不代表它一定没价值。

要清理卷,先列出来:

docker volume ls

再查看具体大小:

sudo du -sh /var/lib/docker/volumes/<volume_name>/_data

确认无用后再删:

docker volume rm <volume_name>

如果不确认,就不要删。尤其是数据库数据卷、应用上传目录、对象存储缓存这类数据,删错就是事故。

第四步:限制 Docker 日志继续膨胀

Docker 默认使用 json-file 日志驱动时,如果没有限制,容器日志可能一直增长。可以编辑 /etc/docker/daemon.json

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

保存后重启 Docker:

sudo systemctl restart docker

这一步会影响正在运行的容器。生产服务要先评估影响,最好选低峰期操作。

另外,这个配置主要影响之后新建或重建的容器。已有容器是否立即生效,需要结合实际部署方式确认,必要时重建容器。

第五步:检查应用日志

如果部署了 Web 服务,也要看应用自己的日志目录:

sudo find /app -name "*.log" -size +100M -exec ls -lh {} \;

确认可以清理后,用 truncate 清空大日志:

sudo truncate -s 0 /app/logs/app.log

长期方案不是反复手动清,而是给应用配置日志轮转。Python 可以用 RotatingFileHandler,系统层面可以用 logrotate,容器层面要限制 Docker 日志大小。

第六步:谨慎查大文件

可以查 100MB 以上的大文件:

sudo find / -xdev -type f -size +100M -exec ls -lh {} \; 2>/dev/null | head -20

这里同样建议用 -xdev,避免跨到其他挂载点。常见可清理对象包括旧压缩包、临时备份、core dump、过期安装包。

不认识的文件不要删,尤其不要碰数据库文件、Docker volume 数据和系统目录。

第七步:考虑长期方案

如果系统盘只有 40GB,而且 Docker 跑得比较多,长期靠清理不是办法。可以考虑把 Docker 数据目录迁移到独立数据盘。

大致流程是:

  1. 挂载数据盘,比如 /data
  2. 停止 Docker
  3. rsync 迁移 /var/lib/docker
  4. /etc/docker/daemon.json 里配置 data-root
  5. 启动 Docker 并验证容器

示例命令:

sudo systemctl stop docker
sudo rsync -aqxP /var/lib/docker/ /data/docker/

示例配置:

{
  "data-root": "/data/docker",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

然后启动 Docker:

sudo systemctl start docker

这一步风险比普通清理高。必须先确认数据盘挂载正常、迁移完整、容器能正常启动,再考虑处理旧目录。不要边迁移边删原数据。

最后

清理后先看根分区:

df -h /

再看 Docker:

docker system df

如果根分区从 84% 降到 60% 左右,说明这次清理有效。但更重要的是后续别再让它涨回来: 限制 Docker 日志,定期看 docker system df, 配置日志轮转,给磁盘使用率加告警, 尽早把 Docker 数据和应用数据从系统盘里拆出去。

磁盘清理不是删得越多越好。更稳的做法是:先定位,后清理;先确认,后删除;先解决当下空间,再处理长期增长源。


本文由 楸木 原创,转载请注明出处。

相关推荐

发现更多