Linux 服务器磁盘突然写满?一套从定位到预防的排查清单
在云服务器上,“磁盘满了”是最常见也最容易引发连锁故障的问题之一:数据库写不进去、服务日志报 No space left on device、甚至连 SSH 登录都变慢。这篇文章整理一套我常用的排查顺序,命令在 EulerOS、CentOS、Ubuntu 上都适用。
一、先确认是“空间满”还是“inode 满”
df -h # 看块空间使用率
df -i # 看 inode 使用率
如果 df -h 还有空间,但 df -i 显示 IUse% 为 100%,说明是小文件太多(常见于会话文件、邮件队列、缓存目录),删大文件解决不了问题,要找文件数量最多的目录:
find / -xdev -type f | cut -d/ -f2-3 | sort | uniq -c | sort -rn | head
二、定位大目录:逐层下钻
du -xh --max-depth=1 / 2>/dev/null | sort -rh | head
-x 表示不跨文件系统,避免把挂载的数据盘、/proc 统计进来。找到最大的目录后,对它重复执行,逐层缩小范围。如果装了 ncdu,交互式浏览会更快:ncdu -x /
三、df 和 du 对不上:被删除但仍被占用的文件
一个经典场景:删了一个几十 GB 的日志,df 显示空间却没释放。原因是还有进程打开着这个文件,文件只是从目录里移除了,数据块还在。
lsof +L1 2>/dev/null | grep -i deleted
找到对应进程后,最稳妥的做法是重启该服务;如果暂时不能重启,可以清空文件描述符指向的内容:
: > /proc/<PID>/fd/<FD>
以后清理正在写入的日志,建议用 truncate -s 0 file.log 或 : > file.log,而不是 rm。
四、常见的“空间大户”
1. 应用日志:/var/log 及业务日志目录,没有配置轮转时会无限增长。
2. journald:journalctl --disk-usage 查看占用,可用 journalctl --vacuum-size=500M 收缩。
3. 容器:docker system df 查看镜像、容器、构建缓存,docker system prune 清理无用对象(执行前确认没有需要保留的已停止容器)。
4. 包管理缓存:yum clean all / apt-get clean。
5. 核心转储:/var/crash、/var/lib/systemd/coredump 中的 core 文件可能非常大。
五、预防:比清理更重要
1. 日志轮转:给业务日志配置 logrotate,例如:
/var/log/myapp/*.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
copytruncate 适合不支持重新打开日志文件的程序。
2. 限制 journald:在 /etc/systemd/journald.conf 中设置 SystemMaxUse=1G,然后 systemctl restart systemd-journald。
3. 数据与系统分离:把数据库、日志、容器数据放到独立的云硬盘上,系统盘写满不会拖垮业务,数据盘也能单独扩容。
4. 监控告警:在云监控里给磁盘使用率配置告警阈值(例如 80% 预警、90% 严重),比等到 100% 再处理从容得多。
5. 预留空间:ext4 默认给 root 预留 5% 空间,紧急情况下 root 仍能登录处理;数据盘可按需用 tune2fs -m 调整。
六、排查顺序小结
df -h / df -i 判断类型 → du 逐层定位 → lsof +L1 检查已删除未释放文件 → 清理日志、容器、缓存 → 配置轮转、限额和告警防止复发。
磁盘问题往往不是一次性的,真正省心的做法是把轮转、限额和告警一次配好,让问题在变成故障之前就被发现。
- 点赞
- 收藏
- 关注作者
评论(0)