1. 首页 > 服务器运维

服务器磁盘告警处理全攻略:从df -h到du、find、ncdu的完整排查流程

当服务器磁盘空间不足时,可通过以下步骤定位占用空间较大的目录和文件,以下操作基于Linux系统(以你提供的df -h输出为例,磁盘 /dev/vda1 挂载在 / 根目录,已使用81%)。df -h 是最基础的磁盘空间查看命令,其中 -h 表示“人类可读”(human-readable),自动将字节数换算为KB、MB、GB等常用单位。输出中的“已用%”列是关注重点,但需要注意的是,该百分比仅反映 block 使用率,并不包含 inode 使用情况——当 inode 耗尽时,即使磁盘仍有剩余空间,也无法创建新文件。因此,在排查磁盘问题时,建议同时执行 df -i 检查 inode 使用率,若 inode 使用也接近100%,则需重点清理大量小文件(如邮件队列、临时缓存文件)。

一、快速定位大文件/目录的常用工具

1. du 命令(磁盘使用情况统计)

功能 :递归扫描指定目录,统计各子目录/文件的磁盘占用大小。du 全称为 “disk usage”,是 Linux 系统中最经典的磁盘分析工具,无需额外安装,几乎在所有发行版中自带。

常用参数
- -h:以人类可读的格式显示(如GB、MB),自动适配单位。
- -s:仅显示目录/文件的总大小(不显示子项),常用于汇总统计。
- -d N:指定扫描深度(N为数字,如-d 1表示仅扫描当前目录的一级子目录)。该参数在GNU版本的 du 中可用,部分老旧系统可能需使用 --max-depth=N 替代。
- -c:在最后一行输出总计大小,便于多个目录合计。
- --exclude=PATTERN:排除匹配特定模式的文件或目录(如排除挂载点),可提高扫描效率。
- -t SIZE:仅显示大小超过指定值的条目(例如 -t 1G 只显示大于1GB的项),适合快速过滤。

操作示例

# 扫描根目录(/)下的一级子目录,按大小排序(从大到小)
du -h --max-depth=1 / | sort -rh
# 查看当前用户家目录(~)的总大小
du -sh ~

输出解读

执行后会列出各目录的大小,如:

40G     /var
30G     /usr
5G      /home

数值最大的目录即为占用空间最多的位置。通常第一行显示的 / 根目录总大小与 df -h 中的已用量基本一致,但要注意 du 默认不统计被删除但仍在被进程占用的文件(这些文件在 /proc/run 中有隐藏引用),因此 du 统计的总和有时会略小于 df 的已用量,属于正常现象。若差值过大(超过几个GB),则需使用 lsof | grep deleted 查找被删除但未释放空间的进程,并重启或 kill 这些进程以真正释放磁盘空间。

同类工具对比dufind 的定位区别在于,du 擅长按目录层级汇总占用,而 find 擅长按单个文件大小筛选。在实际运维中,通常先用 du 找到占用最大的顶级目录,再进入该目录使用 find 查找具体的超大文件,两者配合效率最高。

2. ncdu 命令(可视化磁盘分析工具,需安装)

功能 :交互式图形界面(基于ncurses库),更直观地展示目录结构和文件大小,支持键盘操作(如方向键、删除文件等)。它以类似于“树形图”的方式展示每个目录的占用比例,并可以按大小排序,非常适合于SSH终端中快速浏览。

安装方法 (以CentOS为例):

yum install ncdu -y

(对于Ubuntu/Debian,使用 sudo apt install ncdu;macOS可通过 brew install ncdu 安装)

使用方法

ncdu /  # 扫描根目录
  • 方向键 移动光标,Enter 键进入子目录,d 键标记文件/目录删除(需谨慎!),q 键退出。进入子目录后,按 > 键可查看排序选项(默认按大小降序),按 n 键按文件名排序,按 s 键按大小排序。按 g 键可切换显示百分比或绝对大小。ncdu 还有一个亮点是支持在扫描过程中实时显示进度,对于超大磁盘分区,扫描时间可能较长(例如数TB的存储),此时可加 -q 参数降低CPU优先级,避免影响生产业务。

补充说明ncdu 的删除操作是直接调用 rm -rf,不会进入回收站,因此操作前务必确认光标所在项是否为业务数据。若对安全性要求极高,建议只使用 ncdu 查看而不进行删除,改用 du + find 组合来手动清理。

3. find 命令(查找大文件)

功能 :按文件大小过滤,快速定位单个大文件(如超过1GB的文件)。find 是Linux文件查找的瑞士军刀,除了按大小筛选外,还可结合 -mtime(修改时间)、-type(文件类型)等条件进行多维过滤,避免误删近期修改的重要文件。

常用参数
- -size +Nc:查找大于N字节的文件(c为字节,M为MB,G为GB),注意 + 表示大于,- 表示小于,不加表示精确等于。
- -type f:只查找普通文件(排除目录),避免目录本身被误列为大文件。
- -exec-print:对查找结果执行操作,如 -exec ls -lh {} \; 可列出详细信息。
- -mtime +30:查找修改时间在30天之前的文件,适合清理老旧日志。

操作示例

# 查找根目录下大于1GB的文件
find / -type f -size +1G -exec du -h {} \;
# 查找当前目录下最大的10个文件
find . -type f -exec du -h {} \; | sort -rh | head -n 10

(更实用的组合:find / -type f -size +500M -exec ls -lh {} \; 2>/dev/null | sort -k5 -hr 可列出所有大于500MB的文件并排序)

安全提示find-delete 选项虽然方便,但极其危险,建议先不加 -delete 预览结果,确认无误后再手动执行 rm。尤其是对 / 根目录的全局搜索,必须使用 -xdev 参数限制不跨越挂载点(如 /proc/dev 等虚拟文件系统),否则可能导致系统挂起。

二、常见大文件目录分析

根据Linux系统结构,以下目录常出现大文件,可优先检查:

目录路径常见大文件类型清理建议
/var/log系统日志(.log、.log.gz)删除过期日志,或配置日志轮转(logrotate)自动清理。
/var/lib应用数据(如Docker镜像、数据库文件)清理无用的Docker镜像/容器、数据库备份或临时文件。
/usr/local自定义安装的软件或库删除不再使用的软件安装包或编译缓存。
/home用户文件(如上传文件、备份数据)清理用户无用文件或迁移数据至外部存储。
/tmp临时文件直接清空(需确保无正在使用的进程): rm -rf /tmp/*
/root管理员文件(如脚本、下载文件)清理备份文件或临时脚本。

(在扫描这些目录时,建议先使用 du -sh /var /home /opt /usr/local 等快速评估总大小,然后针对较大的目录深入分析。例如,/var/lib/mysql 下的 binlog 文件(MySQL二进制日志)可能会无限增长,若未配置自动清理策略,可积累数十GB甚至TB级数据。此外,/root/.cache~/.cache 下可能缓存了大量软件包(如pip、npm、yarn),也值得关注。对于容器化环境,/var/lib/docker/overlay2 是Docker存储驱动层,占用空间往往远超预期,需结合 docker system df 查看详情。)

三、清理文件的注意事项

  • 谨慎操作 :避免删除系统关键文件(如/etc/bin/lib目录下的文件)。在删除前,可通过 file 命令判断文件类型,或使用 rpm -qf(CentOS)或 dpkg -S(Ubuntu)查询文件属于哪个系统软件包,若属于核心包则不可删除。
  • 使用rm命令前务必确认文件用途,建议先备份重要数据(可使用 cptar 打包到另一块磁盘或NAS存储)。对于生产环境,强烈建议在变更窗口进行操作,并提前做好回退预案。

日志清理 :系统日志通常位于/var/log,可通过logrotate服务自动管理,避免手动删除导致服务异常。logrotate 是Linux自带的日志轮转工具,通过 /etc/logrotate.conf/etc/logrotate.d/ 下的配置文件控制日志的切割、压缩和保留周期。常见的配置策略为:每天轮转,保留7天,并启用压缩(compress)。若你发现日志占用异常,可执行 logrotate -f /etc/logrotate.conf 强制触发轮转,无需手工 rm。对于某些应用(如Nginx、Tomcat)的访问日志,若未配置轮转,建议立即添加相应配置,并检查日志是否由应用自身管理(如Java的log4j滚动策略),避免双轨制冲突。

应用数据清理 :若使用Docker、MySQL等服务,需通过对应工具清理(如docker system prune、数据库备份删除)。对于Docker,除了 docker system prune -a -f 可清理所有未使用的镜像、容器和卷之外,还应定期执行 docker volume prune 清理无用的匿名卷。对于MySQL,二进制日志(binlog)可通过 PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY); 清理7天前的日志;InnoDB的undo表空间(undo logs)如果配置不当也可能膨胀,需在my.cnf中设置 innodb_undo_log_truncate=ON 并配置回收策略。对于Redis的AOF持久化文件,若启用,应定期执行 BGREWRITEAOF 重写压缩。总之,应用层数据的清理必须遵循对应官方推荐方式,切勿直接删除数据目录下的物理文件,否则极易损坏服务。

保留可用空间 :建议至少保留10%的磁盘空间,避免因空间不足导致系统故障。Linux内核在磁盘使用率达到95%以上时,会触发 reserve blocks 机制(默认保留5%给root用户),但普通服务进程(如Web、数据库)仍可能因无法写入临时文件而崩溃。因此,通过监控工具(如Zabbix、Prometheus)设置告警阈值(如85%警告、90%严重)是更稳健的做法。此外,可利用 autofs 或云存储(如OSS、S3)将低频访问的历史档案迁移至外部存储,从根本上缓解本地磁盘压力。

四、示例操作流程

假设通过du -h --max-depth=1 /发现/var目录占用40GB:

# 进入/var目录,继续扫描二级子目录
du -h --max-depth=1 /var | sort -rh
# 发现/var/lib/docker占用30GB(Docker镜像/容器数据)
docker system prune -a  # 清理所有无用镜像和容器(谨慎操作!)

(进入/var后,可继续执行 du -h --max-depth=1 /var | sort -hr 发现 /var/log/journal 占用20GB,此为systemd日志,可通过 journalctl --vacuum-size=500M 压缩至500MB;再发现 /var/cache/yum 占用5GB,可执行 yum clean all 清除。对于 /var/spool/postfix 中滞留的邮件队列,可检查并清理无效的邮件积压。)

五、进阶技巧与自动化方案

定期扫描与报告:可将 ducron 结合,每周自动生成磁盘使用报告并邮件通知管理员。例如,编写脚本 /usr/local/bin/disk_report.sh,执行 du -sh /* 2>/dev/null | sort -hr | head -20,并通过 mail 发送。同时,可使用 inotify 监控关键目录的变化,当新增大文件时实时告警。

云原生环境下的磁盘管理:在Kubernetes节点上,Pod的本地存储(EmptyDir、hostPath)以及容器运行时(containerd/docker)的镜像层占用往往是主要问题。建议启用镜像垃圾回收(image garbage collection)并设置节点磁盘压力驱逐(eviction)策略,如 --eviction-hard=nodefs.available<10%,让Kubelet自动清理未使用的容器和镜像。

未来趋势:随着存储成本下降和对象存储普及,本地磁盘更多作为缓存或临时空间使用。越来越多的企业采用分布式文件系统(如Ceph、GlusterFS)或云存储网关,将数据持久化到外部存储池,本地仅保留操作系统和运行时依赖。同时,AI驱动的智能运维(AIOps)工具可基于历史数据预测磁盘增长趋势,提前预警扩容需求,避免突发性空间耗尽。

六、总结与最佳实践

通过以上工具和方法,可逐步定位并清理大文件,释放磁盘空间。操作前建议先备份重要数据,并确认文件用途,避免误删导致服务异常。最佳实践清单如下:
1. 每月定期执行 df -hdf -i 检查,关注增长趋势。
2. 为所有应用日志配置 logrotate,保留周期建议不超过30天。
3. 数据库(MySQL、PostgreSQL等)定期清理归档日志和备份文件。
4. 使用 ncdu 作为日常快速分析工具,但禁用其删除功能(使用只读模式)。
5. 监控系统(如Prometheus + Grafana)设置磁盘告警,并结合自动清理脚本(如通过Ansible批量执行)。
6. 对于云服务器,考虑将 /home/var 等目录挂载至独立的数据盘,与系统盘分离,避免系统根目录被占满导致SSH无法登录。

最后,记住一句运维格言:“磁盘管理,预防胜于救火。” 建立规范化的存储使用制度和定期巡检流程,远比应急清理更高效可靠。

本文由主机测评网发布,不代表主机测评网立场,转载联系作者并注明出处:https://zhuji.jb51.net/yunwei/9706.html

联系我们

在线咨询:点击这里给我发消息

Q Q:2220678578