服务器磁盘满了,表现往往很突然:网站打不开、后台报错、MySQL 直接拒绝写入,日志里全是 No space left on device。很多人第一反应是“加硬盘”,但大部分情况下,空间是被日志、备份、Docker 镜像或者几个被删除却仍被占用的文件吃掉的。这篇按“确认、定位、清理、扩容、预防”的顺序,把磁盘清理讲清楚。
一、先确认是哪块盘、是空间还是 inode
df -h df -i
df -h 看容量,df -i 看 inode。两种“满”表现一样,处理方式完全不同:容量满清文件,inode 满要找大量小文件,常见于 session 文件、缓存碎片、邮件队列。如果根分区满了但数据盘还有空间,先确认业务数据实际写到了哪里,别急着删系统文件。
二、定位大目录和大文件
du -sh /* 2>/dev/null | sort -rh | head -20
逐层往下钻,通常很快能定位到 /var/log、/www/wwwlogs、/var/lib/docker、/home 备份目录。装了 ncdu 会更直观:
apt install -y ncdu && ncdu /
找单个大文件:
find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null
注意 -xdev 不要跨文件系统,否则会扫到挂载的网络盘和临时目录,既慢又容易误判。
三、已删除但空间没释放
这是最容易被忽略的情况:文件被 rm 掉了,但进程还开着句柄,空间不会释放。
lsof | grep deleted
找到对应进程后重启服务即可释放,常见的是 Nginx、PHP-FPM、MySQL 的日志文件被手动删除但进程没重启。也可以在不重启的情况下清空:
: > /proc/<pid>/fd/<fd>
清理日志优先用 truncate 或 logrotate,不要直接 rm 正在写入的日志文件。
四、日志与 journal 清理
systemd 的 journal 很容易涨到几个 G:
journalctl --disk-usage journalctl --vacuum-size=500M
Nginx 日志按站点分开,访问日志增长最快。配置 logrotate 按天切割并保留 7 到 14 天:
/www/wwwlogs/*.log {
daily
rotate 14
compress
missingok
notifempty
sharedscripts
postrotate
nginx -s reopen
endscript
}
MySQL 的 binlog 也要管,尤其是主从环境:
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);
五、Docker 占空间的清理
docker system df docker system prune -a
prune 会删掉未使用的镜像、容器、网络,执行前确认没有还在用的镜像。Docker 日志默认不限制大小,一个跑疯的容器能写满整块盘,建议在 daemon.json 里统一限制:
{
"log-driver": "json-file",
"log-opts": { "max-size": "50m", "max-file": "3" }
}
改完重启 Docker 生效。生产环境不要随手执行 prune,先看清楚要删什么。
六、数据库和备份文件
MySQL 的数据目录、慢日志、临时文件都可能突然膨胀。检查:
du -sh /var/lib/mysql/*
备份目录同样是大头,本地保留多份全量备份很快就会吃满磁盘。建议本地只留最近 3 到 7 天,历史备份传到对象存储,并设置生命周期规则自动清理。
七、扩容:云盘和文件系统要一起扩
清理只能救急,长期还是要把容量加上去。云服务器扩容分两步:先在控制台扩容云盘,再在系统里扩文件系统。ext4 用:
resize2fs /dev/vda1
xfs 用:
xfs_growfs /
如果用了 LVM,还要先 pvresize、lvextend。扩容前务必做快照,确认分区和文件系统类型再操作,命令用错会丢数据。
八、预防:监控和自动清理
磁盘问题九成可以提前发现。给根分区和数据盘都加上使用率监控,超过 80% 告警、90% 严重告警;日志统一走 logrotate;Docker 限制日志大小;备份设置保留策略;再写一个每周执行的清理脚本,删除 7 天前的临时文件和旧日志。
如果业务增长快,提前规划数据盘和挂载点,把日志、数据库、附件分开存放,一块盘满了不至于整个站点瘫痪。
九、最后总结
磁盘满了先别慌,按 df 确认、du 定位、lsof 查占用、分类清理的顺序走,大部分问题十分钟内能定位。真正要养成习惯的是日志轮转、备份保留和容量监控,这三件事做好,磁盘告警就不会变成线上事故。