1. 问题现象与快速诊断
当Linux服务器突然报错"No space left on device"时,就像汽车的油表突然亮起红灯,意味着系统已经无法继续写入新数据。这种情况最常见于日志文件疯狂增长吞噬磁盘空间,但实际原因可能更为复杂。我们先通过几个快速命令定位问题:
# 查看整体磁盘使用情况(人类可读格式) df -h # 检查各目录占用空间(按大小排序) du -sh /* 2>/dev/null | sort -h如果发现/var/log目录异常膨胀(比如占用超过80%空间),基本可以确定是日志文件问题。但资深运维都知道,磁盘满报警背后可能隐藏着四种完全不同的情况:
- 真实空间耗尽:常规文件过多导致,常见于日志、缓存文件堆积
- inode耗尽:存在海量小文件,即使空间未满也无法创建新文件
- 文件删除未释放:进程仍持有已删除文件的句柄
- 挂载点覆盖:多个存储设备挂载到同一目录
2. 日志文件专项清理方案
2.1 定位罪魁祸首
使用组合命令快速找出大体积日志文件:
# 查找大于100MB的日志文件(按修改时间倒序) find /var/log -name "*.log" -size +100M -exec ls -lth {} + | head -20典型需要关注的日志类型包括:
- Nginx/Apache访问日志
- 系统审计日志(audit.log)
- 内核日志(kern.log)
- 应用服务日志(如mysql、redis)
2.2 安全清理策略
直接rm删除日志可能影响正在运行的进程,推荐使用以下方法:
# 清空日志内容(保留文件句柄) truncate -s 0 /var/log/nginx/access.log # 按时间归档旧日志 find /var/log/nginx -name "*.log" -mtime +30 -exec gzip {} \;重要提示:对于关键业务日志,建议先确认日志轮转(Logrotate)配置是否正常。检查/etc/logrotate.d/目录下相关配置,确保设置了合理的轮转策略。
2.3 自动化日志管理
配置logrotate示例(以Nginx为例):
/var/log/nginx/*.log { daily missingok rotate 30 compress delaycompress notifempty create 0640 www-data adm sharedscripts postrotate /usr/sbin/nginx -s reload endscript }执行测试:
logrotate -vf /etc/logrotate.d/nginx3. 深度空间回收技巧
3.1 处理"幽灵"文件
当df显示空间已满但du统计不足时,可能存在被进程占用的已删除文件:
# 安装lsof工具 yum install lsof -y || apt-get install lsof -y # 查找被删除但仍被占用的文件 lsof | grep deleted | awk '{print $2,$4,$7,$9}' | sort -k3 -nr处理方案:
# 优雅重启相关进程 systemctl restart service_name # 或通过PID直接释放 kill -9 pid_number3.2 Inode耗尽解决方案
检查inode使用情况:
df -i清理策略:
# 查找小文件聚集目录 find / -type d | while read -r dir; do echo "$dir : $(find "$dir" -maxdepth 1 -type f | wc -l)"; done | sort -k3 -nr | head -20 # 批量删除特定类型小文件(如临时文件) find /tmp -name "*.tmp" -delete4. 高级预防措施
4.1 文件系统监控方案
配置Prometheus监控规则示例:
- alert: DiskSpaceCritical expr: 100 - (node_filesystem_avail_bytes{mountpoint="/"} * 100 / node_filesystem_size_bytes{mountpoint="/"}) > 90 for: 10m labels: severity: critical annotations: summary: "Disk space is running out (instance {{ $labels.instance }})" description: "{{ $labels.mountpoint }} on {{ $labels.instance }} has only {{ $value }}% available space left"4.2 自动化清理脚本
创建智能清理脚本/usr/local/bin/disk_cleaner.sh:
#!/bin/bash THRESHOLD=90 CURRENT=$(df / --output=pcent | tail -1 | tr -d '%') if [ "$CURRENT" -ge "$THRESHOLD" ]; then # 自动清理30天前的日志 find /var/log -name "*.log" -mtime +30 -delete # 清理临时文件 rm -rf /tmp/* # 发送通知 echo "Disk cleanup performed at $(date)" | mail -s "Disk Space Alert" admin@example.com fi设置每日定时任务:
(crontab -l 2>/dev/null; echo "0 3 * * * /usr/local/bin/disk_cleaner.sh") | crontab -5. 疑难问题排查指南
5.1 特殊场景处理
Docker磁盘占用:
# 查看Docker磁盘使用 docker system df # 清理无用资源 docker system prune -afLVM卷扩容:
# 查看物理卷 pvdisplay # 扩展逻辑卷 lvextend -L +10G /dev/mapper/vg-root resize2fs /dev/mapper/vg-root5.2 性能优化建议
对于高频写入场景:
- 考虑使用tmpfs内存文件系统存放临时文件
- 对日志目录使用单独的分区
- 启用日志压缩功能(如Zstandard)
# 创建内存文件系统挂载点 mount -t tmpfs -o size=512m tmpfs /mnt/ramdisk