首页 > Technology > 正文

Linux 磁盘空间满了怎么办?排查与清理实操

fenij 2026-07-31 258 Technology

服务器突然告警:磁盘使用率 100%。网站打不开,数据库写不进去,连 SSH 登录都卡半天才进。这种事每个运维都遇到过,处理思路其实很固定:先定位谁占了空间,再决定删什么。

磁盘占用排查命令速查

命令 作用 示例
df -h 看整体磁盘使用 df -h /
du -sh * 看目录大小 du -sh /var/*
ncdu 交互式磁盘分析 ncdu /var
find -size 找大文件 find / -size +500M
lsof | grep deleted 找已删但未释放 lsof +L1
/var/log
日志最常占满
🔧
/tmp
临时文件清理
📊
docker
镜像/卷占空间

第一步:看整体使用情况

登录上去先跑 df -h,看是哪个分区满了。大部分时候是根分区 / 或者数据分区 /var 撑爆了。输出长这样:

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   38G   20K 100% /

Use% 100%,Avail 几乎为零。记住这个分区,后面所有排查都围绕它。

第二步:找大目录

du 从根目录逐层找谁最占空间:

du -h --max-depth=1 / 2>/dev/null | sort -rh | head -20

这会列出根目录下每个子目录的大小,从大到小排序。找到最大的那个,进去再跑一次同样的命令,一层层缩小范围。一般几步就能定位到具体目录。

常见的重灾区:

  • /var/log — 日志文件没做轮转,或者某个服务疯狂报错刷日志
  • /var/lib/docker — Docker 镜像和容器层堆积
  • /tmp — 临时文件没清理
  • /home/用户名 — 用户数据或者备份文件堆积
  • /var/www — 网站上传的附件、缓存文件

第三步:找大文件

目录定位了,再看具体哪个文件最大:

find /var/log -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9}' | sort -rh

这条命令找指定目录下大于 100MB 的文件,按大小排序。把 /var/log 换成你定位到的大目录。

日志文件占满怎么处理

这是最常见的情况。先看是哪个日志文件膨胀:

ls -lhS /var/log/ | head -10

如果有个文件比如 syslog 或者 nginx/error.log 涨到了几个 G,直接清空它:

truncate -s 0 /var/log/nginx/error.log

truncate 而不是 rm,因为有些服务持有文件句柄,直接删文件空间不会释放,得重启服务才行。truncate 清空内容但保留文件句柄,服务不受影响。

然后检查为什么日志暴涨。通常是某个服务在疯狂报错,比如 MySQL 连接失败、PHP fatal error。看日志内容找到根因,修掉它,否则过几天又会涨满。

长期方案是配置 logrotate。检查 /etc/logrotate.d/ 下有没有对应服务的配置,没有就加一个。

Docker 占满怎么处理

如果 /var/lib/docker 是大头,用 Docker 自带的清理命令:

docker system prune -a --volumes

这条命令删掉所有停止的容器、无用的网络、悬空的镜像和卷。如果有些容器还在运行但你确定不需要了,先 docker stop 再删。

注意 --volumes 会删除未被任何容器引用的卷,如果有数据卷你不舍得丢,先 docker volume ls 看一眼,确认没有重要数据再执行。

已删除但空间没释放

有时候你删了文件,df 显示空间没变。这是因为有进程还在持有被删文件的句柄。用这条命令找出来:

lsof +L1 | grep deleted

输出会显示哪个进程持有已删除的文件。重启对应进程(或者 kill 掉),空间就会释放。

清理包管理缓存

两个常见的缓存清理:

apt clean && apt autoclean && apt autoremove -y

对 CentOS/RHEL:

yum clean all && dnf autoremove

一般能省几百 MB,不多但聊胜于无。

更多服务器运维实操,请访问 fenij.com

常见问题

问:删了文件 df 还是显示 100% 怎么办?
答:有进程持有已删除文件的句柄。运行 lsof +L1 | grep deleted 找到进程,重启或 kill 该进程即可释放空间。

问:logrotate 已经配了但日志还是很大?
答:检查 logrotate 是否真的在跑。logrotate -d /etc/logrotate.d/你的配置 做一次 dry-run。如果配置没报错,看 /var/log/syslog 里有没有 logrotate 的执行记录。cron 可能没装或者没启动。

问:inode 用完了但磁盘空间还有?
答:小文件太多会耗尽 inode。运行 df -i 看 inode 使用率。用 find / -xdev -printf '%h\n' | sort | uniq -c | sort -k1 -n | tail -5 找哪个目录下文件最多,然后清理。

进阶:云盘扩容不生效与预防监控

现在的服务器大多在云上,磁盘是「云盘」,光在系统里扩容不够。你在阿里云/腾讯云/AWS 控制台把盘从 40G 加到 100G,回头 df -h 还是 40G——因为分区表和文件系统还没扩。步骤分两层:

# 1. 扩分区(把第 1 个分区撑满整块盘)
growpart /dev/vda 1
# 2. 扩文件系统
resize2fs /dev/vda1          # ext4
xfs_growfs /                 # xfs 自动撑满

LVM 场景不一样:先 pvresize /dev/vda1 让物理卷认新空间,再 lvextend -r -l +100%FREE /dev/mapper/xxx

文件系统 扩分区 扩文件系统
ext4growpart /dev/vda 1resize2fs /dev/vda1
xfsgrowpart /dev/vda 1xfs_growfs /
LVMpvresizelvextend -r

别一满就删文件救急,治本要预防。写个 cron 脚本每天查使用率,超过 80% 就发告警(邮件或企业微信/钉钉 Webhook):

df -h | awk 'NR>1 && int($5) > 80 {print $0}'

把这条塞进 /etc/cron.daily/ 或配个监控面板(如 Netdata、node_exporter+Grafana)。等磁盘 100% 才处理,数据库往往已经崩了。另外提醒:删大文件前一定先 lsof +L1 | grep deleted 确认没进程占用,否则空间不释放(前面讲过);日志类文件用 truncate -s 0 而不是 rm。

延伸答疑

控制台扩了容,df 还是老大小?
只扩了云盘,没扩分区和文件系统。按上面 growpart + resize2fs 两步补齐。

Docker 占的空间想单独挂盘?
/var/lib/docker 迁到新挂载点,或建盘后改 docker 的 data-root 配置,重启 docker 服务生效。

df 显示有空间但写不进文件?
看 inode:df -i。小文件太多 inode 耗尽也会写失败,按前面方法找文件最多的目录清理。

怎么长期监控磁盘?
cron + df 阈值告警最轻量;正经点用 Netdata、node_exporter+Grafana,能看历史趋势提前扩容。

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: