磁盘空间和inode耗尽是Linux服务器故障排查中最常见的一类问题,典型症状是应用写日志报错”No space left on device”、数据库写入失败、甚至SSH登录卡顿。本文覆盖从定位到处置的完整流程,所有命令在CentOS与Ubuntu上通用。
第一步:确认是空间耗尽还是inode耗尽
“No space left on device”有两种成因:磁盘块用完,或者inode用完。小文件海量的场景(邮件队列、session文件、缓存碎片)经常出现块没用完但inode耗尽的情况。两条命令分别确认:
# 查看磁盘块使用率
df -h
# 查看inode使用率
df -i
重点关注Use%或IUse%达到90%以上的挂载点。两个指标任何一个接近100%,都会触发同样的报错,处置路径完全不同,所以排查第一步必须先分清。
快速定位大文件与大目录
块空间耗尽时,先找最大的目录再缩小范围:
# 一级目录占用排行
du -h --max-depth=1 / 2>/dev/null | sort -rh | head -20
# 在可疑目录里继续下钻
du -h --max-depth=2 /var 2>/dev/null | sort -rh | head -20
找到大目录后,列出其中最大的文件,直接确认可清理对象:
# 列出/var/log下大于200MB的文件
find /var/log -type f -size +200M -exec ls -lh {} \; | awk '{print $5, $9}'
# 找出7天内被修改过的大文件(还在活跃写入的)
find / -xdev -type f -size +500M -mtime -7 2>/dev/null
高频元凶按出现概率排序:应用日志未轮转(单个文件几十GB)、MySQL binlog未清理、Docker容器日志与悬空镜像、core dump文件、/tmp下的临时文件、包管理器缓存。
日志文件已删除但空间未释放的处理
一个经典陷阱:日志文件已经rm删除,df显示空间没回来。原因是进程仍持有该文件的文件描述符,块空间要等进程关闭句柄才释放。确认方法:
# 查看已删除但仍被占用的文件
lsof +L1 | grep deleted
两种处置方式:能重启的服务直接重启进程释放句柄;不能重启的服务(如线上数据库),用截断方式替代删除:
# 对持有句柄的文件截断而非删除
: > /var/log/huge_app.log
# 或按进程fd路径截断
: > /proc/$(pgrep -f myapp)/fd/3
inode耗尽的定位与清理
inode耗尽意味着目录里塞了海量小文件。定位哪个目录文件数最多:
# 统计根下各一级目录的文件数量
for d in /*; do echo -n "$d: "; find "$d" -xdev | wc -l; done
# 常见小文件聚集地
find /var/spool -type f | wc -l
find /tmp -type f | wc -l
ls /var/lib/php/sessions | wc -l
处置方式按业务判断:邮件队列文件用postqueue清理;PHP session设置gc概率并删除过期session;海量小文件用find批量删除,比rm -rf *更快且不易报参数过长:
# 海量小文件批量删除
find /var/spool/mqueue -type f -mtime +7 -delete
根因治理:轮转、限额与告警
清理只能救急,防止复发要靠三件事。
日志轮转。确认logrotate配置覆盖所有应用日志,nginx、PHP-FPM、自研服务都要有轮转规则:
# /etc/logrotate.d/myapp 示例
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
}
copytruncate选项配合未实现日志重开信号的应用,避免轮转后进程继续写旧句柄。
目录限额。对不可控的写入目录(上传目录、临时目录)用quota或独立分区隔离,即使写满也不影响系统盘。
监控告警。磁盘使用率超过80%告警、超过90%升级处理,inode同样纳入监控。一个够用的cron脚本:
#!/bin/bash
THRESHOLD=85
df -H --output=pcent,target | tail -n +2 | while read pct target; do
used=$(echo "$pct" | tr -d ' %')
if [ "$used" -ge "$THRESHOLD" ]; then
echo "$(hostname) ${target} usage ${used}%" | mail -s "Disk Alert" ops@example.com
fi
done
Docker主机额外注意:配置daemon.json限制容器日志大小(max-size与max-file),定期执行docker system prune清理悬空资源,这两项能消掉容器主机上大半的磁盘隐患。磁盘问题处置的核心思路是”先分清块与inode,再定位大对象,清理后必须补上轮转与告警”,只清理不治理的机器,通常一个月内会再次告警。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-fu-wu-qi-ci-pan-kong-jian-yu-inode-hao-jin-pai-cha/