搬瓦工 VPS 磁盘空间满了怎么办?日志、Docker 和 inode 清理

上传图片失败、数据库报 No space left on device,不一定要重装系统。先确认满的是根分区、独立数据盘,还是 inode;随后才决定清理日志、缓存或容器。直接删除占用最大的目录,可能把数据库和网站附件一起删掉。
本文以 Debian / Ubuntu 为例。故障期间保留现有 SSH 会话;若已经无法登录,先从 KiwiVM 控制台 查看系统状态。下面把只读检查与会删除历史数据的操作分开列出。
一、容量、inode 和只读状态分别检查

先在出问题的服务器执行:
# 把 /var/www 换成实际写入失败的目录
df -hT / /var/www
df -i / /var/www
findmnt -T /var/www
df -hT 查看空间和文件系统类型,df -i 查看 inode。小文件数量非常多时,即使还有若干 GB,也可能无法再创建文件。findmnt 则帮助确认路径实际上落在哪块盘,避免在根分区清理半天,却没有改善已经满了的数据盘。[1]
如果报的是 Read-only file system,先查看内核消息,不要把它当成普通容量不足:
sudo journalctl -k -b --no-pager -n 150
发现 I/O error、文件系统损坏或挂载失败时,先保存数据和错误记录,不要为了恢复写入而反复强制重新挂载。涉及文件系统检查时,应使用对应工具并满足离线条件。
二、逐层找目录,不要一开始扫描所有挂载点
sudo du -xhd1 / 2>/dev/null | sort -h
sudo du -xhd1 /var 2>/dev/null | sort -h
sudo du -xhd1 /var/log 2>/dev/null | sort -h
-x 不跨入其他文件系统,-d1 只列当前下一层。先看一级目录,再进入明显异常的目录。命令仍会产生读取负载,正在严重卡顿的系统不要反复全盘扫描;这里为了减少无关权限信息隐藏了标准错误,某个目录结果异常时,应去掉重定向重查。[2]
常见增长源包括网站备份、Nginx/PHP 错误日志、数据库二进制日志、上传目录、Docker 镜像和容器日志。数据库日志也不能按普通文本日志处理,尤其不要直接删数据库数据文件来“腾空间”。
只列出大文件,先不删除:
sudo find /var/log -xdev -type f -size +200M -printf '%s %p\n' \
| sort -nr | head -n 20
上面的 200 MiB 是本例筛选条件,不是“超过这个大小就该删”。文件名包含特殊换行时,文本列表会不便阅读,应进一步用文件管理工具核对实际对象。
三、先处理明确可回收的内容

软件包缓存
确认不需要保留本地安装包后,可以执行 sudo apt clean。它清理下载缓存,不会卸载已安装软件。不要把 apt autoremove 当成同一件事;后者会卸载被判定不再需要的包,必须先阅读待删除清单。
systemd 日志
# 只读:查看当前 journal 大小 sudo journalctl --disk-usage会删除历史日志:保存必要故障记录后,才执行sudo journalctl --rotate
sudo journalctl --vacuum-size=300M
300 MiB 是示例保留预算。vacuum 主要处理已归档日志,活动文件和其他日志也占空间,因此执行后不保证 --disk-usage 恰好等于这个数。先保留入侵或故障证据,再做清理。[3]
网站日志与数据库日志
Nginx 的日志由 logrotate 管理时,先检查轮转配置、服务是否正确重新打开日志,以及错误是否仍在每秒大量产生。只压缩旧文件、却不修复错误原因,磁盘很快还会再次涨满。数据库 binlog 的保留与清理要通过数据库机制,并考虑复制与恢复链;不要用 rm 删除正在使用的日志文件。
四、Docker 占空间时怎么处理

sudo docker system df -v
sudo docker ps -a
sudo docker volume ls
# 选择真实容器名,确认数据保存位置
sudo docker inspect your-container --format '{{json .Mounts}}'
docker system df 的可回收空间是按引用关系计算的,不是对数据价值的判断。停止的容器可能仍有未导出的文件;没有挂载到现有容器的数据卷,也可能是下一次准备恢复的数据库。[4]
确认一个无用镜像后,优先用 docker image rm IMAGE_ID 定向删除,并保留业务的上一稳定版本。本文不提供带 --volumes 的全量清理命令,也不要直接删除 /var/lib/docker 或 /var/lib/containerd。
容器日志持续膨胀时,在对应 Compose 服务中合并以下配置,再按维护计划重建该服务:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
这限制的是该服务的新日志轮转,不会替你回收所有旧容器内容。已有容器需要按实际部署方式应用新配置;重建前先确认数据在卷或绑定目录中。不要直接改 Docker 管理的 JSON 日志。[5]
五、文件删了,为什么 df 仍然没下降
sudo lsof +L1
文件从目录中移除后,仍可能被进程打开。lsof +L1 可帮助找出这类对象,再结合 PID、文件大小和业务归属判断。优先让相关服务正常重新打开日志,必要时安排一次受控重启,不要看到 PID 就强制结束数据库或 SSH。[6]
另一种情况是稀疏文件、硬链接、预留空间或挂载覆盖,让 du 与 df 的统计口径不同。两者不一致并不自动表示“系统算错了”。
六、inode 用尽时怎么处理
inode 问题常见于缓存、会话、邮件队列或大量零碎文件。先缩小到目标目录,再查询 inode 分布:
sudo du --inodes -x -d 2 /var/cache 2>/dev/null | sort -n | tail -n 20
只清理应用明确允许过期的对象,优先使用它自身的缓存或保留策略。不要为了回收 inode 清空全部 /tmp、上传目录或队列目录。对正在接收请求的站点,先控制生成速率,否则清理和新增会一直互相抵消。[2]
七、复查业务,再决定是否扩容

清理后重新检查目标挂载点,测试一次图片上传、后台保存和数据库写入,并观察日志是否又在增长。可以为磁盘空间与 inode 分别设置预警;例如 80% 持续一段时间提示检查,90% 提升级别,这只是起始参考,数据库和备份应保留更充足的绝对空间。
若正常数据已经长期接近容量上限,再比较扩容与迁移。搬瓦工 Basic VPS 深度介绍与适用场景 可用于理解规格定位;更换服务器与 KiwiVM 迁移机房 不是同一操作。清理或扩容前,重要文件仍应按照 快照与独立备份的方法 保存。
常见问题
可以直接删除 /var/lib/mysql 吗?
不能。这里可能就是数据库主体,删除不属于正常空间维护。先查表、日志和备份,再通过数据库支持的操作处理。
docker system prune 是不是安全清理?
它会按对象引用关系删除内容,而不是判断你是否还需要数据。先读待删除说明,重要卷和回滚镜像不要交给全局清理。
空间恢复后还报错怎么办?
检查应用是否仍持有错误状态、文件系统是否只读、写入路径是否正确,以及数据库是否正常恢复。不要只凭 df 有空闲就宣布故障结束。

