4.2 磁盘满了怎么办:先找罪魁,再动手删
先给一个判断
磁盘满的排查就一句话:先定位是谁吃的,再决定删什么。 df -h 只能告诉你“满了”,du 才能告诉你“谁吃的”。很多人一看磁盘红了就急着清缓存、删日志,结果删了半天空间没释放多少,因为真正的大头是某个几十 G 的备份包或者容器日志。删错文件的空间是回不来的,删之前先看清楚。
第一步:确认是不是真的满了
# 看各分区的使用率(重点看 Use% 和挂载点)
df -h
# 看 inode 占用(小文件太多会先耗尽 inode)
df -i
一个经典误区:df 显示 100% 满,但你 du 加起来不到一半。这种情况通常是有文件被删了但进程还拿着句柄——空间没真正释放。验证方法:
# 列出所有"已删除但仍被占用"的文件
lsof +L1 2>/dev/null | awk 'NR==1 || $7+0 > 1048576' | head -20
看到这种文件,重启占用它的进程(或整个应用容器),空间立刻就回来了。典型例子:某个网站日志被直接 rm 删掉,但 OpenResty 还在往里写。
第二步:找到大文件
# 根目录下各目录占用(从大到小排,只看前十)
du -sh /* 2>/dev/null | sort -rh | head -10
# 顺藤摸瓜,继续进最大的那个目录
du -sh /var/* 2>/dev/null | sort -rh | head -10
# 直接揪出所有大于 500M 的文件
find / -xdev -type f -size +500M 2>/dev/null | head -20
du 一定要加 -x 或只在同一个分区内查,不然把别的挂载点(比如云数据盘)也算进来,数字大得吓人还没用。
1Panel 环境的三个重灾区
| 目录 | 装的什么 | 能不能清 |
|---|---|---|
/opt/1panel |
面板数据、应用、备份、日志 | 用面板的缓存清理,别手 rm |
/var/lib/docker |
镜像、容器日志、存储卷 | 用 docker 命令清,见下 |
| 网站日志目录 | OpenResty 的访问/错误日志 | 用日志切割,见 4.4 节 |
Docker 占用的查看和清理:
# 看各类 Docker 占用(镜像、容器、日志、卷分开显示)
docker system df -v
# 清掉停止的容器、无用镜像、构建缓存(占用空间的大户)
docker system prune -f
# 更彻底:连无用存储卷一起清(确认没有要用的卷再执行)
docker system prune -a -f --volumes
一句提醒:
docker system prune -a会删掉所有未被运行中容器使用的镜像。力气很大,删之前确认没有“停着备用”的应用。稳妥的做法是先docker images看一眼,心里有数再执行。
inode 占用:磁盘没满但写不进文件
症状很有欺骗性:df -h 才用 30%,但应用报“No space left on device”,数据库写不进数据,网站传不了图。这时候去看 df -i,多半是 100%。
inode 是文件的户口本——每个文件占一个,不管文件多小。一个目录里塞几百万个小文件(典型是邮件队列、缓存碎片、Redis 持久化的小 key 文件), inode 先用光,磁盘空间还剩一大堆。
# 找出哪个目录文件数最多(统计较慢,建议先在可疑根目录跑)
for d in /*; do
[ -d "$d" ] && echo "$(find $d -xdev -type f 2>/dev/null | wc -l) $d"
done | sort -rn | head -10
处理思路:找到那个海量小文件目录,确认它是什么(多半是某应用的缓存或队列),用应用自己的清理命令清,或者直接整目录删——删几百万个小文件用 rm -rf 会很慢,可以用 rsync --delete 空目录覆盖,快得多。
安全清空间的标准顺序
按照“从安全到危险”的顺序删,每删一步看一下 df -h:
- 面板缓存清理:工具箱 → 缓存清理,勾选系统垃圾、容器垃圾、临时文件、系统日志——这是最安全的一步,面板自己知道什么能删;
- Docker 无用镜像:
docker system prune -f,清掉停止容器和无用镜像; - 旧备份文件:备份列表里超过保留份数的老备份,确认不需要后删;
- 容器日志:见 4.4 节的日志切割,别上来就删;
- 应用数据——这一步开始就要格外谨慎了,删之前先备份。
一条红线:/opt/1panel 下的数据库数据目录、应用数据卷,不要用命令行直接删。要删走面板的备份/应用管理入口,面板知道它们的依赖关系。手 rm 容易留下半拉子状态,应用起不来你都不知道少了什么。
面板里的磁盘工具
1Panel 在 系统 → 磁盘管理 里能看各磁盘的容量、使用率和挂载点;未分区的云数据盘可以在页面里直接分区、格式化、挂载,支持 ext4 和 xfs。如果新买了一块数据盘,比起往系统盘里硬塞,挂一块新盘、把备份目录挪过去,是更彻底的解决办法。
分区有风险:官方文档明确说分区和创建文件系统会清除目标磁盘上的原有数据,1Panel 不会替你判断磁盘里有没有有效数据,操作前一定核对设备名。
一个完整的复现与修复
现象:面板提示磁盘空间不足,网站传图片失败,数据库也开始报错。
排查过程:
df -h—— 根分区 97%,确实快满了;du -sh /* | sort -rh | head——/var占了 60G,最大头;du -sh /var/* | sort -rh | head——/var/lib/docker占 40G;docker system df -v—— 容器日志占了 18G,其中一个应用容器单日志就 12G(这个应用跑了大半年,从没配过日志大小限制)。
修复:
- 先用面板 缓存清理 清掉系统垃圾和停止容器,腾出 3G 应急(先让数据库能写,止血第一);
- 然后按 4.4 节的方法给所有容器加上日志大小限制,截掉历史日志;
- 最后给备份任务设上保留份数,防止备份无限堆积。
复盘要点:这个案例里真正的问题不是“磁盘小”,而是没有任何东西在限制增长——日志无限制地写、备份无限制地留。清空间是治标,给每个会增长的东西设上限,才是治本。
预防:让磁盘别再悄悄满
| 手段 | 怎么做 | 一次配置长期生效 |
|---|---|---|
| 备份保留份数 | 计划任务里设保留份数 | 自动滚动删除旧备份 |
| 网站日志切割 | 计划任务 → 切割网站日志 | 配合保留份数自动清 |
| 容器日志限制 | 修改 Docker daemon 配置 | 见 4.4 节 |
| 监控告警 | 面板监控关注磁盘曲线 | 临满前能看出来 |
一个习惯:df -h 这条命令成本为零,每次登上服务器顺手敲一下。磁盘从 70% 涨到 95% 通常要好几周,它从来不是突然满的,只是你没看。
本节要点
- 先
df -h/df -i,确认是空间满还是 inode 满,两者处理方式完全不同; - 删文件后空间没释放,用
lsof +L1查“被删但仍被占用”的文件,重启进程即可; - 找大文件用
du -sh | sort -rh逐层深入,Docker 用docker system df; - 清空间从面板缓存清理开始,应用数据目录不要手 rm;
- 治本之道是给备份、日志设置保留份数和大小限制。
更多磁盘管理能力见 1Panel 官方文档:磁盘管理,以官方文档为准。
下一节:磁盘清完了,如果 free -h 里available 内存也见底——4.3 节说内存和慢查询怎么治。
