Linux 文件系统 inode 耗尽故障排查实战
故障现象
某生产服务器出现无法创建新文件的情况,具体表现为:
1 2 3 4 5 6 7 8
| $ touch test.txt touch: cannot touch 'test.txt': No space left on device
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/sda1 100G 20G 80G 20% /
|
磁盘使用率仅 20%,但系统提示”No space left on device”,这通常意味着 inode 耗尽而非磁盘空间不足。
故障诊断
1. 确认 inode 使用情况
1 2 3 4 5
| $ df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda1 6553600 6553500 100 100% / /dev/sdb1 131072000 1000000 130072000 1% /data
|
根分区 inode 使用率已达 100%,确认为 inode 耗尽故障。
2. 定位 inode 消耗源
1 2 3 4 5
| $ for i in /*; do echo $i; find $i -xdev -type f | wc -l; done | sort -k2 -nr | head -20
$ find / -xdev -type f | cut -d "/" -f 2-3 | sort | uniq -c | sort -rn | head -20
|
常见的高 inode 消耗目录:
/var/log/ - 日志文件过多
/var/spool/postfix/ - 邮件队列堆积
/tmp/ - 临时文件未清理
/var/cache/ - 缓存文件积累
- 应用数据目录 - 小文件过多
3. 深入分析具体目录
1 2 3 4 5
| $ find /var/log -type f | cut -d "/" -f 4 | sort | uniq -c | sort -rn | head -20
$ find /var -type f -size -1k | wc -l
|
故障处理
方案一:清理无用文件(临时解决)
1 2 3 4 5 6 7 8 9 10 11
| $ find /var/log -type f -name "*.log" -mtime +7 -delete
$ find /var -type f -empty -delete
$ find /tmp -type f -atime +3 -delete
$ find /var/spool/postfix -type f -delete
|
方案二:日志轮转优化(长期解决)
检查并优化 logrotate 配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $ cat /etc/logrotate.conf $ ls /etc/logrotate.d/
$ cat /etc/logrotate.d/nginx /var/log/nginx/*.log { daily rotate 7 compress delaycompress missingok notifempty create 0640 www-data adm sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript }
|
方案三:应用层优化
针对产生大量小文件的应用:
1 2 3 4 5 6 7
|
$ tar -czf archive_$(date +%Y%m%d).tar.gz /path/to/small/files/ $ rm -rf /path/to/small/files/*
|
方案四:文件系统调优(根本解决)
1 2 3 4 5 6 7 8 9
| $ tune2fs -l /dev/sda1 | grep -i inode
$ mkfs.ext4 -i 8192 /dev/sda1
$ mkfs.xfs /dev/sda1
|
监控与预防
1. 添加 inode 监控告警
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
$ cat /etc/prometheus/rules/inode_alert.yml groups: - name: inode_alerts rules: - alert: InodeUsageHigh expr: (1 - (node_filesystem_files_free / node_filesystem_files)) * 100 > 80 for: 5m labels: severity: warning annotations: summary: "Inode 使用率过高" description: "{{ $labels.instance }} 的 {{ $labels.mountpoint }} 分区 inode 使用率超过 80%"
- alert: InodeUsageCritical expr: (1 - (node_filesystem_files_free / node_filesystem_files)) * 100 > 90 for: 2m labels: severity: critical annotations: summary: "Inode 使用率危急" description: "{{ $labels.instance }} 的 {{ $labels.mountpoint }} 分区 inode 使用率超过 90%"
|
2. 定期巡检脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #!/bin/bash
THRESHOLD=80 EMAIL="admin@example.com"
while read -r line; do filesystem=$(echo "$line" | awk '{print $1}') inodes=$(echo "$line" | awk '{print $2}') iused=$(echo "$line" | awk '{print $3}') ifree=$(echo "$line" | awk '{print $4}') iusepct=$(echo "$line" | awk '{print $5}' | tr -d '%') mounted=$(echo "$line" | awk '{print $6}')
if [ "$iusepct" -gt "$THRESHOLD" ]; then echo "警告:$mounted 分区 inode 使用率 ${iusepct}%" | mail -s "Inode 告警" $EMAIL fi done < <(df -i | tail -n +2)
|
3. 添加定时任务
1 2 3
| $ crontab -e 0 2 * * * /usr/local/bin/inode_check.sh
|
故障复盘
根因分析
- 直接原因:某应用日志配置不当,未启用日志轮转,导致日志文件无限增长
- 间接原因:
- 缺少 inode 使用率监控
- 未设置日志保留策略
- 文件系统选型不当(ext4 固定 inode 数量)
改进措施
- ✅ 优化应用日志配置,启用 logrotate
- ✅ 添加 inode 监控告警(阈值 80% 警告,90% 危急)
- ✅ 编写定期清理脚本,清理 30 天前的日志
- ✅ 新服务器采用 xfs 文件系统(动态 inode)
- ✅ 将 inode 检查纳入日常巡检清单
总结
inode 耗尽是 Linux 运维中常见但容易被忽视的问题。关键要点:
- 诊断:使用
df -i 快速确认是否为 inode 问题
- 定位:使用
find 命令逐层统计文件数量
- 处理:清理无用文件 + 优化日志轮转 + 应用层优化
- 预防:添加监控告警 + 定期巡检 + 合理选型
记住:磁盘空间充足 ≠ 可以正常写入,inode 同样重要!