Linux 服务器磁盘空间告警排查:从 df 到 lsof 的完整流程
云服务器磁盘使用率告警是最常见的运维事件之一。本文整理一套按顺序执行的排查流程,覆盖空间被大文件占用、inode 耗尽、文件已删除但空间未释放三类典型原因,命令均可直接复现。 ## 1. 先确认是空间还是 inode `df -h` 看空间,`df -i` 看 inode。两者任一接近 100% 都会导致写入失败。 ``` df -hT df -i ``` - `Use%` 高而 `IUse%` 低:大文件占用,进入第 2 步。 - `IUse%` 高而 `Use%` 低:小文件过多(会话、缓存、邮件队列),进入第 4 步。 - 两者都不高但应用仍报错:检查是否为只读挂载或配额限制。 ## 2. 逐级定位大目录 从根目录开始,用 `-x` 限制在同一文件系统内,避免扫描到其它挂载点。 ``` du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -15 # 选出最大的目录后继续下钻 du -xh --max-depth=1 /var 2>/dev/null | sort -rh | head -15 ``` 常见元凶:`/var/log`、`/var/lib/docker`、`/tmp`、应用自身的 `logs` 目录、数据库 binlog。 找出单个大文件: ``` find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null ``` ## 3. du 与 df 不一致:已删除但仍被进程持有的文件 现象:`rm` 删了大日志,`df` 却没降。原因是进程仍持有该文件描述符,空间在进程关闭文件前不会释放。 ``` lsof +L1 | grep -i deleted # 或者 lsof -nP | grep '(deleted)' | sort -k7 -n -r | head ``` 处理方式: - 首选重启或让进程重新打开日志(如 `systemctl reload nginx`、发送 `USR1` 信号,视程序而定)。 - 无法重启时,可清空文件描述符指向的内容: ``` # 与 取自 lsof 输出 : > /proc//fd/ ``` 清空前确认该文件确实无需保留。 ## 4. inode 耗尽的定位 统计各子目录的文件数量: ``` for d in /var/*; do echo "$(find "$d" -xdev 2>/dev/null | wc -l) $d"; done | sort -rn | head ``` 找到目录后确认是否为可清理的临时数据,再分批删除。目录内文件极多时,`rm -rf *` 可能报参数过长,改用: ``` find /path/to/dir -type f -mtime +7 -delete ``` ## 5. 常见清理动作 - 日志:配置 `logrotate`,设置 `rotate`、`size`、`compress`;systemd 日志用 `journalctl --vacuum-size=500M`。 - Docker:`docker system df` 查看占用,确认后用 `docker system prune`(会删除停止的容器与悬空镜像,执行前核对)。 - 包缓存:`apt clean` 或 `yum clean all`。 - 数据库:按业务策略清理 binlog,不要直接 `rm` 数据文件。 ## 6. 预防 - 在云监控中为磁盘使用率配置告警,阈值建议留出处理时间(具体指标与配置入口以控制台为准)。 - 日志目录独立挂载数据盘,避免写满系统盘。 - 数据盘容量不足时,可按云平台文档扩容云硬盘并扩展文件系统,操作前先做快照。 ## 小结 排查顺序:`df -h/-i` 判类型 → `du` 下钻定位 → `lsof +L1` 排查已删除未释放 → 清理并配置轮转与告警。删除操作前务必确认文件用途,生产环境先快照或备份。