Linux 磁盘空间排查
磁盘满有三种情况:空间真满 / Inode 耗尽 / 文件已删但空间未释放。不分清楚就删文件,可能白费力气。
快速定位表
| 现象 | 第一步命令 | 后续步骤 |
|---|---|---|
| df -h 显示 Use%=100% | du -sh /* \| sort -rh |
逐层定位大目录 |
| df -h 有空间但无法写文件 | df -i |
找小文件密集目录,清理旧文件 |
| df 满但 du 统计不到 | lsof \| grep deleted |
通知进程重载或重启 |
| 空间充足但业务慢 | iostat -xz 1 5 |
检查 %util/await/aqu-sz |
8 个排查命令
① df -h — 空间使用率
df -h
# Use%=100% → 立即处理
# Use%=90~99% → 预警
关注 Avail 列(非 root 用户可用)。ext4 默认保留 5% 给 root,数据盘可调低:
tune2fs -m 1 /dev/vdb1 # 保留块从 5% 降到 1%
② df -i — Inode 使用率
小文件太多时 inode 先于空间耗尽。每个文件消耗一个 inode(不管大小)。
df -i
# IUse%=100% → 小文件过多
# 定位小文件目录
for dir in /*/; do echo -n "$dir: "; find "$dir" -xdev -type f 2>/dev/null | wc -l; done
# 逐级统计文件数
find / -xdev -type f | awk -F/ '{$NF=""; print $0}' | sort | uniq -c | sort -rn | head -10
③ du -sh — 逐层定位大目录
du -h --max-depth=1 / | sort -rh | head -10 # 根一级
du -h --max-depth=1 /var/ | sort -rh | head -10 # 深入
du -sh /var/log/nginx/ # 定位到具体目录
④ lsof | grep deleted — 已删文件未释放
最容易被忽略的场景。rm 删文件后,如果有进程仍持有句柄,空间不会释放。
sudo lsof | grep deleted
# java 3456 root 23w REG 202,1 2147483648 12345 /var/log/app/access.log (deleted)
解决方法(推荐顺序):
# 安全:通知进程重载
kill -USR1 <PID> # Java/log4j
nginx -s reopen # Nginx
# 临时:清空文件内容(生产安全,不依赖信号)
: > /proc/<PID>/fd/<FD_NUMBER>
# 强制:重启进程
systemctl restart <service>
根因与预防: logrotate 默认 create 指令会导致旧文件句柄残留。应改用 copytruncate:
/var/log/nginx/*.log {
daily
rotate 30
copytruncate # 复制后截断,不改变 inode
compress
}
⑤ find — 查找大文件
find / -xdev -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh | head -20
find /var/log -type f -size +1G -exec ls -lh {} \; 2>/dev/null
find /data -type f -size +500M -mtime +7 -exec ls -lh {} \; 2>/dev/null
⑥ ncdu — 交互式磁盘分析
du 的交互式替代品:
ncdu / # 方向键浏览,d 删除,q 退出
⑦ iostat -xz — IO 性能分析
空间充足但业务慢 → 查 IO 性能瓶颈:
iostat -xz 1 5
| 指标 | 含义 | HDD 警戒 | SSD 警戒 |
|---|---|---|---|
| %util | 磁盘忙碌 | > 80% | 参考价值有限 |
| r_await / w_await | 读写延迟 | > 20ms | > 2ms |
| aqu-sz | 队列深度 | > 1 | > 并行度 |
⑧ journalctl --disk-usage — systemd 日志占用
journalctl --disk-usage
journalctl --vacuum-time=7d # 清理 7 天前
journalctl --vacuum-size=500M # 限制最大 500MB
# 永久配置 /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M
MaxFileSec=7day
生产环境清理流程
记录现场 → 定位 → 确认业务 → 备份 → 清理 → 验证 → 配置长期策略
# 1. 记录现场
df -h > /tmp/disk_clean_$(date +%s).before
# 2-3. 定位并确认业务归属
ls -la /var/log/nginx/access.log.*
# 与业务方确认
# 4. 备份后再清理
gzip -c /var/log/nginx/access.log > /backup/nginx/access.log.gz && rm access.log
# 5. 验证
df -h && df -i
# 6. 长期策略
# logrotate + crontab 定期清理
预防措施
- 日志轮转必须配置 — 检查未被 logrotate 覆盖的日志文件
- 三级告警:Warning > 80% / Critical > 90% / Emergency > 95%
- 独立分区:/var/log、/data 独立分区避免写满根分区
- 定期巡检:每周扫描使用率和大文件增长
注意事项
- 根分区满时不要重启服务器
- 生产慎用 rm -rf,优先
truncate -s 0 file或echo "" > file - df 和 du 差异 > 5% → 优先查
lsof | grep deleted - %util 100% ≠ 磁盘损坏,先看 aqu-sz 和 await
关联页面
| 页面 | 关联点 |
|---|---|
| server-performance-four-dimensions | 磁盘 IO 性能排查(五维排查总纲) |
| node-troubleshooting | K8s Node DiskPressure 处理(节点磁盘清理) |
| linux-kernel-tuning-production | 内核参数调优(IO 调度器等) |
| linux-essential-commands-reference | Linux 30 个高频命令速查(df/du/find 等磁盘管理命令速查) |
| linux-compression-tools-comparison | 压缩工具对比与日志归档压缩策略 |
| journalctl-log-tracking-guide | journalctl 命令完全指南(磁盘管理联动) |
| linux-mass-file-deletion-guide | Linux 海量文件删除指南 — find/perl/rsync/shred 四种方法性能对比 |
| linux-hardware-info-and-ops-guide | Linux 硬件信息查询与软件管理命令速查 — CPU/内存/磁盘/网络/主板全覆盖 |
| linux-raid-lvm-basics-guide | Linux RAID 与 LVM 基础入门 — RAID 0/1/5/6/10 级别对比、LVM 分 |
| linux-disk-inspection-tools-guide | 磁盘排查工具实战指南 — iostat 阈值解读/smartctl 健康诊断/lsscsi 设备列表 |
| storage-troubleshooting | K8s 存储排障(PVC/挂载) |