磁盘空间爆满排查与解决手册

一、错误现象

场景报错信息
保存文件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 allapt 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

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注