一、错误现象
| 场景 | 报错信息 |
|---|---|
| 保存文件 | write error: No space left on device |
| 创建目录 | mkdir: cannot create directory 'test': No space left on device |
| 编辑文件 | E667: Fsync failed |
| 数据库 | ERROR 3 (HY000): Error writing file ... (No space left on device) |
二、两步定位法
第一步:先看磁盘空间(df -h)
df -h
输出示例:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 40G 0 100% /
如果 Use% 达到 100%,就是磁盘空间满了,跳转至 方案A
第二步:再看 Inode 使用率(df -ih)
df -ih
输出示例:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 256K 256K 0 100% /
如果 IUse% 达到 100%,就是 Inode 用尽了,跳转至 方案B
三、解决方法
【方案A】磁盘空间满 —— 找大文件
# 查看根目录下最大的5个文件夹
du -sh /* 2>/dev/null | sort -hr | head -n 5
# 进入最大的目录,继续深入查找
cd /var
du -sh * 2>/dev/null | sort -hr | head -n 5
# 找到大文件后,确认是否可以删除
ls -lh /var/log/messages
rm -f /var/log/messages # 确认无用后删除
# 如果是日志文件,建议用 truncate 清空而非直接 rm(避免进程还在写)
truncate -s 0 /var/log/nginx/access.log
# 清理包缓存
yum clean all # CentOS/RHEL
apt clean # Ubuntu/Debian
# 清理 Docker 垃圾(如果有)
docker system prune -a -f
【方案B】Inode 耗尽 —— 找小文件
Inode 耗尽意味着文件数量太多,而不是总大小大。
# 查看哪个目录文件数量最多
find / -xdev -type f | cut -d/ -f2 | sort | uniq -c | sort -nr | head -10
# 常见罪魁祸首:
ls -la /var/spool/postfix/maildrop/ # 邮件队列积压
ls -la /tmp/ # 临时文件
ls -la /var/log/ # 大量小日志
# 批量删除(以邮件队列为例)
rm -rf /var/spool/postfix/maildrop/*
# 清理超过30天的小日志文件
find /var/log -type f -name "*.log" -mtime +30 -delete
四、快速命令汇总
| 目标 | 命令 |
|---|---|
| 看磁盘空间 | df -h |
| 看 Inode 使用率 | df -i |
| 找根目录最大目录 | du -sh /* 2>/dev/null | sort -hr | head -5 |
| 找当前目录最大目录 | du -sh * 2>/dev/null | sort -hr | head -5 |
| 找大文件 | find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null |
| 清空日志文件 | truncate -s 0 /var/log/xxx.log |
| 删除30天前日志 | find /var/log -name "*.log" -mtime +30 -delete |
| 清理包缓存 | yum clean all 或 apt clean |
| 清理 Docker 垃圾 | docker system prune -a -f |
五、注意事项
| 注意事项 | 说明 |
|---|---|
| 不要乱删 | 不确定的文件先 ls -l 查看大小和时间,确认无用再删 |
| 日志文件 | 如果进程正在写日志,不要直接 rm,用 truncate -s 0 清空 |
| /tmp 目录 | 重启会自动清理,但生产环境不要依赖重启 |
| 数据库文件 | 不要直接删数据库文件,用数据库自身的清理机制 |
六、预防措施
# 1. 定期监控
# 写个脚本每天检查磁盘使用率,超过90%报警
# 2. 日志轮转
# 配置 logrotate,避免日志无限增长
vim /etc/logrotate.d/nginx
# 3. 定时清理
# crontab 每周清理一次
0 2 * * 0 find /var/log -name "*.log" -mtime +30 -delete
发表回复