磁盘空间不足问题定位与解决(运维实战)
一、核心排查流程
1.1 全局查看磁盘使用概况
- 核心目标:快速定位使用率过高的分区,同时排查inode耗尽问题
- 关键命令:
# 以人类可读格式查看各分区空间
df -h
# 查看各分区inode使用情况
df -i
# 查看文件系统类型(影响扩容命令)
df -T
- 输出说明:重点关注使用率%列,根分区(/)使用率≥90%需紧急处理
1.2.1 定位满盘分区下的大目录
查找当前目录下最大的3个文件夹并统计其大小
- 实现脚本(兼容 Linux)
# 核心逻辑:统计大小 → 过滤无关行 → 排序 → 取前3 → 格式化输出
du -h –max-depth=1 2>/dev/null | \\
# 过滤掉当前目录(.)的统计行,只保留子文件夹
grep -v "^[0-9.]*[KMG]B \\.$" | \\
# 按人类可读的大小逆序排序(1GB > 100MB 这种逻辑)
sort -hr | \\
# 只取前3行(最大的3个)
head -3 | \\
# 格式化输出,让结果更清晰
awk '{print "文件夹:" $2 "\\t大小:" $1}'
- 适配 macOS 的版本
du -h -d 1 2>/dev/null |grep -v "^[0-9.]*[KMG]B \\.$" | sort -hr |head -3 | awk '{print "文件夹:" $2 "\\t大小:" $1}'
1.2.2 定位满盘分区下的大文件
- 核心目标:精准定位占用空间的大目录/文件,缩小排查范围
- 关键命令:
# 查看根分区下一级目录大小(不跨文件系统)
du -xh –max-depth=1 /
# 聚焦重点目录(如/var/log)
du -sh /var/*
# 查找大于100M的文件并按大小降序排序
find / -type f -size +100M -exec ls -lh {} ; | awk '{print $5, $9}' | sort -hr
# 排查已删除但未释放的文件(程序占用句柄)
lsof | grep deleted
1.3 安全清理无效文件
- 核心原则:优先清空而非删除,避免程序句柄失效
- 常用清理命令:
# 清空大日志文件(保留文件本身)
truncate -s 0 /var/log/messages
# 删除过期日志轮转文件
rm -f /var/log/*.log-202*
# 删除/tmp下7天前的临时文件
find /tmp -type f -mtime +7 -delete
# 重启占用deleted文件的进程释放空间
systemctl restart [进程名]
1.4 进阶处理(清理后仍不足)
- LVM扩容(xfs文件系统):
# 扩容逻辑卷
lvextend -L +10G /dev/mapper/centos-root
# 刷新xfs文件系统大小(ext4用resize2fs)
xfs_growfs /dev/mapper/centos-root
- 迁移大目录到新磁盘:
# 移动数据目录
mv /var/lib/mysql /data/mysql
# 创建软链接保持程序访问路径不变
ln -s /data/mysql /var/lib/mysql
1.5 保留最新日志100MB(清除旧日志保留新日志)
要保留日志的最新 100MB 内容(尾部内容),应使用 tail 命令(专门处理文件尾部),这是日志处理的行业通用做法,且更安全:
# 核心命令:保留app.log最新的100MB内容,覆盖回原文件
tail -c 100M app.log > app.log.tmp && \\
mv app.log.tmp app.log && \\
chmod –reference=app.log.bak app.log # 可选:保持原文件权限(先备份再执行)
命令解释(新手友好):
- tail -c 100M app.log:读取 app.log 尾部(最新)的 100MB 内容;
- ->app.log.tmp:把读取到的内容写入临时文件(避免直接重定向导致的文件句柄冲突);
- mv app.log.tmp app.log:用临时文件替换原日志文件(原子操作,无数据丢失);
- chmod –reference:保持原文件的权限 / 所属用户(可选,但生产环境建议加)。
二、自动化运维脚本
2.1 磁盘空间监控告警脚本(disk_monitor.sh)
#!/bin/bash
# 配置项
ALERT_THRESHOLD=85 # 磁盘使用率告警阈值(%)
INODE_THRESHOLD=90 # inode使用率告警阈值(%)
MONITOR_PART="/" # 监控分区(多个分区用空格分隔)
EMAIL="admin@example.com" # 告警接收邮箱
# 检查磁盘使用率
check_disk_usage() {
for part in $MONITOR_PART; do
usage=$(df -h $part | grep -v Filesystem | awk '{print $5}' | sed 's/%//g')
if [ $usage -ge $ALERT_THRESHOLD ]; then
msg="【磁盘告警】分区$part使用率达到${usage}%,超过阈值${ALERT_THRESHOLD}%!
当前磁盘使用详情:
$(df -h $part)"
echo "$msg" | mail -s "磁盘空间不足告警" $EMAIL
echo "告警已发送:$msg"
fi
done
}
# 检查inode使用率
check_inode_usage() {
for part in $MONITOR_PART; do
inode_usage=$(df -i $part | grep -v Filesystem | awk '{print $5}' | sed 's/%//g')
if [ $inode_usage -ge $INODE_THRESHOLD ]; then
msg="【Inode告警】分区$part inode使用率达到${inode_usage}%,超过阈值${INODE_THRESHOLD}%!
当前inode使用详情:
$(df -i $part)"
echo "$msg" | mail -s "Inode耗尽告警" $EMAIL
echo "告警已发送:$msg"
fi
done
}
# 主执行
check_disk_usage
check_inode_usage
- 使用说明:
- 安装依赖:yum install -y mailx(CentOS)/apt install -y mailutils(Ubuntu)
- 定时执行(每小时):
crontab -e
0 * * * * /bin/bash /usr/local/scripts/disk_monitor.sh > /dev/null 2>&1
2.2 大文件快速排查脚本(find_large_files.sh)
#!/bin/bash
# 配置项
TARGET_DIR="/" # 排查根目录
MIN_SIZE="100M" # 最小文件大小(支持1G、500M等)
LOG_FILE="/tmp/large_files_$(date +%Y%m%d).log"
# 检查目录有效性
if [ ! -d $TARGET_DIR ]; then
echo "错误:目录$TARGET_DIR不存在!"
exit 1
fi
# 排查并输出日志
echo "===== 大文件排查结果($(date))=====" > $LOG_FILE
echo "排查目录:$TARGET_DIR,最小文件大小:$MIN_SIZE" >> $LOG_FILE
echo "—————————————-" >> $LOG_FILE
find $TARGET_DIR -type f -size +$MIN_SIZE -exec ls -lh {} ; | awk '{print $5, $9}' | sort -hr >> $LOG_FILE
# 统计文件数量
total=$(wc -l $LOG_FILE | awk '{print $1 – 4}')
echo "—————————————-" >> $LOG_FILE
echo "共找到$total个大于$MIN_SIZE的文件" >> $LOG_FILE
# 屏幕输出提示
echo "排查完成!结果已保存到:$LOG_FILE"
echo "前10个最大文件:"
head -14 $LOG_FILE | tail -10
- 使用说明:
- 赋予执行权限:chmod +x find_large_files.sh
- 定时执行(每周日凌晨2点):
crontab -e
0 2 * * 0 /bin/bash /usr/local/scripts/find_large_files.sh > /dev/null 2>&1
三、运维拓展(预防大于治理)
3.1 日志轮转(logrotate)配置
- 配置示例(Nginx):/etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily # 每天轮转
rotate 7 # 保留7天日志
compress # 压缩旧日志
delaycompress # 延迟压缩写入中的日志
missingok # 日志不存在时不报错
notifempty # 空日志不轮转
create 0644 nginx nginx # 新建日志权限/属主
postrotate # 轮转后重载Nginx
systemctl reload nginx
endscript
}
3.2 监控体系搭建
- 基础监控工具:Zabbix / Prometheus+Grafana
- 核心监控指标:
- node_filesystem_usage_percent(磁盘使用率)
- node_filesystem_inodes_used_percent(inode使用率)
- 告警阈值:
- 普通告警:使用率≥80%
- 紧急告警:使用率≥90%
- 告警渠道:邮件、钉钉、企业微信
3.3 分区规划最佳实践
- 根分区(/):至少50G,避免系统文件占满
- 数据分区(/data、/var/lib/mysql):单独分区,便于扩容
- 分区类型:优先使用LVM,支持在线扩容,无需停机
四、核心总结
- 排查核心:先通过df -h/df -i定位异常分区,再用du/find找大文件,重点排查lsof | grep deleted(已删未释放文件)
- 清理原则:用truncate清空日志而非rm删除,避免程序句柄失效
- 预防关键:日志轮转+定时清理+监控告警,LVM分区是扩容最优选择
网硕互联帮助中心







评论前必须登录!
注册