Linux磁盘空间快速排查实战:从基础命令到自动化脚本
当服务器磁盘空间告急时,系统管理员往往需要在最短时间内定位问题根源。本文将带你从基础命令开始,逐步构建一套完整的磁盘空间排查体系,最终形成一个自动化分析脚本,帮助你在5分钟内快速定位磁盘占用95%的罪魁祸首。
1. 磁盘空间排查基础:df与du命令解析
在Linux系统中,df和du是磁盘空间分析的两把利剑,它们各司其职却又相辅相成。
df命令(Disk Filesystem)用于查看文件系统的整体磁盘使用情况。一个典型的用法是:
df -hT这里的参数组合会产生清晰易读的输出:
-h:以人类可读格式显示(KB、MB、GB)-T:显示文件系统类型
典型输出示例:
Filesystem Type Size Used Avail Use% Mounted on /dev/vda1 ext4 50G 47G 1.2G 98% /du命令(Disk Usage)则用于分析具体目录和文件的磁盘占用情况。最常用的组合是:
du -sh /*这个命令会显示根目录下所有一级子目录的总大小:
-s:只显示总计大小-h:人类可读格式
关键区别:
| 命令 | 作用范围 | 最佳使用场景 |
|---|---|---|
| df | 文件系统级别 | 快速查看哪个分区空间不足 |
| du | 目录/文件级别 | 定位具体占用空间的位置 |
提示:当df显示空间不足但du统计的总和远小于分区大小时,可能存在文件已被删除但进程仍占用的情况(下文会详细说明)
2. 进阶排查技巧:定位大文件与特殊场景
2.1 快速找出大文件
组合使用find和sort命令可以高效定位大文件:
find / -type f -size +100M -exec ls -lh {} + 2>/dev/null | sort -k5 -rh这个命令的执行逻辑:
- 从根目录开始查找大于100MB的普通文件(
-type f -size +100M) - 以易读格式列出文件详情(
ls -lh) - 按文件大小降序排序(
sort -k5 -rh)
2.2 处理已删除但未释放的空间
当发现df显示的已用空间远大于du统计结果时,可能是被删除的文件仍被进程占用。使用lsof命令可以找出这些"幽灵文件":
lsof | grep deleted | sort -k7 -rn输出示例:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 12345 root 1w REG 253,1 536870912 123456 /var/log/app.log (deleted)处理方案:
- 重启相关进程(最彻底)
- 清空文件内容:
truncate -s 0 /proc/[pid]/fd/[fd]
2.3 特殊目录分析
某些目录需要特别关注:
/var/log:系统日志目录/tmp:临时文件- Docker存储目录:
/var/lib/docker - 数据库数据目录:如PostgreSQL的
/var/lib/pgsql
针对日志文件的快速分析:
du -ah /var/log | sort -rh | head -203. 自动化排查脚本开发
将上述命令整合成一个自动化脚本disk_analyzer.sh:
#!/bin/bash # 磁盘空间分析工具 v1.2 THRESHOLD=90 # 空间使用百分比阈值 TOP_N=10 # 显示前N个大目录/文件 # 检查root权限 if [ "$(id -u)" -ne 0 ]; then echo "请使用root权限运行此脚本" >&2 exit 1 fi # 1. 检查各分区使用情况 echo -e "\n\033[1;34m=== 分区空间使用情况 ===\033[0m" df -hT | awk 'NR==1 || $6+0>'$THRESHOLD'' # 2. 检查inode使用情况 echo -e "\n\033[1;34m=== Inode使用情况 ===\033[0m" df -i | awk 'NR==1 || $5+0>'$THRESHOLD'' # 3. 分析根目录空间占用 echo -e "\n\033[1;34m=== 根目录空间占用TOP $TOP_N ===\033[0m" du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -n $TOP_N | awk '{printf "%-10s %s\n", $1, $2}' # 4. 查找大文件 echo -e "\n\033[1;34m=== 大文件查找(>100MB) ===\033[0m" find / -type f -size +100M -exec du -h {} + 2>/dev/null | sort -rh | head -n $TOP_N # 5. 检查被删除未释放的文件 echo -e "\n\033[1;34m=== 被删除但未释放的文件 ===\033[0m" lsof -nP | grep -i deleted | sort -k7 -nr | head -n $TOP_N | awk '{printf "%-10s %-10s %s\n", $2, $3, $NF}' # 6. 特殊目录检查 echo -e "\n\033[1;34m=== 特殊目录检查 ===\033[0m" for dir in /var/log /tmp /var/lib/docker; do [ -d "$dir" ] && echo -e "\n$dir:" && du -sh $dir/* done脚本功能说明:
- 分区空间检查:突出显示使用率超过阈值的分区
- Inode检查:防止大量小文件耗尽inode
- 根目录分析:快速定位占用最大的子目录
- 大文件查找:找出超过100MB的文件
- 幽灵文件检测:找出已删除但未释放空间的文件
- 特殊目录检查:重点分析常见问题目录
注意:运行此脚本需要root权限,因为它需要访问系统所有目录
4. PostgreSQL数据库空间专项排查
数据库往往是磁盘空间的大户,这里以PostgreSQL为例介绍专项排查方法:
4.1 数据库大小查询
SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) as size FROM pg_database ORDER BY pg_database_size(pg_database.datname) DESC;4.2 表空间分析
SELECT table_schema || '.' || table_name AS table_full_name, pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) as size FROM information_schema.tables ORDER BY pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC LIMIT 10;4.3 WAL日志管理
PostgreSQL的WAL日志可能占用大量空间,检查命令:
du -sh /var/lib/postgresql/12/main/pg_wal/调整WAL日志保留策略:
ALTER SYSTEM SET wal_keep_segments = 32; -- 保留32个段文件 SELECT pg_reload_conf(); -- 重载配置5. 实用清理策略与注意事项
5.1 安全清理原则
- 日志文件:使用
logrotate管理而非直接删除 - 临时文件:确认不再使用后再清理
- 数据库文件:使用SQL命令清理而非直接删除文件
5.2 常用清理命令
日志文件轮转:
logrotate -f /etc/logrotate.conf清理旧内核(CentOS/RHEL):
package-cleanup --oldkernels --count=2Docker系统清理:
docker system prune -af5.3 预防措施
- 设置磁盘空间监控告警
- 对重要分区保留10-20%的缓冲空间
- 对大目录设置配额限制
- 定期执行预防性维护
# 添加cron任务定期检查 0 3 * * * /usr/local/bin/disk_analyzer.sh > /var/log/disk_check.log通过本文介绍的方法和脚本,你可以在磁盘空间告急时快速定位问题根源。记住,预防胜于治疗,建立完善的监控和维护机制才是解决磁盘空间问题的长久之计。