问题场景
生产环境磁盘使用率突破阈值,需要快速定位空间占用源并制定清理策略。
诊断链路
1. 全局视图:df定位分区
df -h # 人类可读格式 df -i # 检查inode耗尽情况
2. 目录级排查:du统计占用
# 一级目录占用排序 du -sh /* 2>/dev/null | sort -hr | head -10 # 深度遍历(谨慎使用) du -h --max-depth=2 /var | sort -hr | head -20
3. 文件级定位:find精准打击
# 查找大文件(>100mb)
find / -type f -size +100m -exec ls -lh {} \; 2>/dev/null
# 查找最近7天修改的大文件
find /var/log -type f -mtime -7 -size +50m
常见陷阱
陷阱1:已删除文件未释放空间
lsof | grep deleted # 需要重启占用进程或kill -hup
陷阱2:隐藏的docker占用
docker system df # 查看docker空间占用 docker system prune -a --volumes # 清理悬空资源
陷阱3:inode耗尽但空间充足
df -i # 检查inode使用率 find / -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n
预防措施
- 配置logrotate自动轮转日志
- 设置磁盘使用率告警(建议80%阈值)
- 定期清理临时文件和旧备份
- 监控docker镜像和容器数量
方法补充
磁盘空间耗尽(no space left on device)是linux运维中最常见的问题之一。下文将带你走通从系统级检查到目录级定位的完整排查链路,覆盖df、du、lsof、find等核心工具的使用场景和技巧。
快速体检:df - 查看整体磁盘使用情况
df(disk free)用于查看文件系统的总容量、已用空间、可用空间和挂载点。它是排查的第一步,能快速锁定哪个分区已经饱和。
基础用法
df -h # 以人类可读的格式显示(gb/mb)
输出示例:
filesystem size used avail use% mounted on
/dev/sda1 98g 78g 15g 84% /
/dev/sda2 500g 498g 2.0g 100% /home
- use% 100%:该分区已满,需要进一步排查。
- avail 0:可用空间为零,系统可能无法写入日志或创建临时文件。
常用选项
| 命令 | 说明 |
|---|---|
df -h | 人类可读大小(自动k/m/g) |
df -i | 查看inode使用情况(小文件过多也会导致“空间不足”) |
df -t | 显示文件系统类型(如xfs、ext4) |
df --total | 汇总所有文件系统的总计 |
特殊情况:df 显示已满,但 du 统计很小
原因可能是:
- 文件已被删除,但仍有进程打开该文件(句柄未释放)。
- 挂载点下有“隐藏”的旧文件(如子目录被另一设备挂载覆盖)。
精确定位:du - 分析目录和文件大小
du(disk usage)用于统计目录或文件的真实磁盘占用。当df发现分区满后,用du逐级深入,找出大文件或大目录。
常用命令组合
# 查看当前目录下所有子目录的大小,按人类可读排序 du -sh * | sort -hr # 查看整个分区下最大的10个目录(深度1) sudo du -h /home --max-depth=1 | sort -hr | head -10 # 更全面的扫描:跳过某些目录,排除proc、sys等伪文件系统 sudo du -h --exclude=/proc --exclude=/sys --max-depth=1 / | sort -hr
参数详解
| 参数 | 含义 |
|---|---|
-s | 汇总(只显示总计) |
-h | 人类可读格式 |
-d n 或 --max-depth=n | 只显示n层子目录 |
--exclude=pattern | 排除匹配的目录/文件 |
-a | 同时显示文件(默认只显示目录) |
-c | 最后显示总和 |
常用定位大文件的快速命令
# 查找超过1gb的文件
find /home -type f -size +1g -exec ls -lh {} \; 2>/dev/null
# 查找超过500mb且最近7天修改过的文件
find /var/log -type f -size +500m -mtime -7 -exec ls -lh {} \;进阶诊断:inode 耗尽与文件句柄泄漏
有时候 df -h 显示空间有余,但系统仍报“no space left on device”。这通常是 inode耗尽 或 文件句柄未释放 导致的。
检查inode使用率
df -i
输出示例:
filesystem inodes iused ifree iuse% mounted on
/dev/sda1 5.2m 5.2m 0 100% /home
iuse% 100%:inode已满,通常因为存在大量小文件(如缓存、邮件队列)。
解决方案:
# 找到包含大量小文件的目录 sudo find /home -type f -printf "%h\n" | sort | uniq -c | sort -rn | head -10 # 进入该目录,清理旧文件(例如超过30天的日志) find /home/cache -type f -mtime +30 -delete
文件被删除但未释放句柄(lsof)
当进程正在使用某个文件时,即使你执行了rm,磁盘空间也不会立即释放,直到进程关闭该文件或重启。
诊断方法:
# 查看所有已删除但仍被进程占用的文件 lsof | grep deleted # 更精确:只看某个分区下的已删除文件 lsof /home | grep deleted
输出示例:
java 12345 root 14w reg 8,1 10485760 123456 /home/log/app.log (deleted)
解决:重启对应进程(systemctl restart java-app)或重定向其输出(> /proc/12345/fd/14,但通常重启更可靠)。
常见场景与解决策略
/var/log 日志文件过大
# 查看日志目录占用 sudo du -sh /var/log/* | sort -hr # 清理3个月前的系统日志(以journalctl为例) sudo journalctl --vacuum-time=3d # 安全截断日志文件(保留最新1000行) sudo tail -n 1000 /var/log/syslog > /tmp/syslog.tmp && sudo mv /tmp/syslog.tmp /var/log/syslog
docker/容器存储膨胀
# 查看docker占用空间 docker system df # 清理未使用的镜像、容器、卷和构建缓存 docker system prune -a -f # 进一步清理所有停止的容器和未使用的卷 docker volume prune -f
/tmp 目录临时文件堆积
# 清理超过24小时未访问的临时文件 sudo find /tmp -type f -atime +1 -delete sudo find /var/tmp -type f -atime +1 -delete
数据库文件(如mysql、postgresql)过大
- 检查数据库的数据目录(通常在
/var/lib/mysql或/var/lib/pgsql)。 - 使用数据库自身的清理命令:
optimize table、vacuum full。 - 考虑归档旧数据或迁移到更大的存储卷。
自动化监控与预警
为了避免手工排查,可以设置定期监控和告警。
使用cron + df 定时检查并发送邮件
# 编辑root的crontab
sudo crontab -e
# 添加如下行(每小时检查一次,使用率超过90%发邮件)
0 * * * * /usr/bin/df -h | awk 'nr>1 && $5+0 > 90 {print $0}' | mail -s "disk alert" admin@example.com集成到 prometheus + grafana
安装 node_exporter 采集磁盘指标,配置告警规则:disk_used_percent > 90%。
使用 ncdu 交互式分析(推荐)
# 安装 sudo apt install ncdu # debian/ubuntu sudo yum install ncdu # rhel/centos # 使用 ncdu /home
上下键导航,d 删除文件,q 退出,界面友好,适合交互式清理。
到此这篇关于linux中磁盘空间排查实战指南的文章就介绍到这了,更多相关linux磁盘空间排查内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论