
磁盘空间不足是生产环境中最常见、也最容易引发连锁故障的问题之一。当磁盘写满时,日志无法落盘、数据库无法提交事务、服务进程甚至无法启动,最终演变成一次业务中断事故。作为运维人员,与其等到故障发生后再手忙脚乱地清理,不如提前建立一套存储监控与磁盘配额体系,在容量逼近阈值之前就发出预警,并借助配额机制约束用户对空间的无限占用。本文将从容量监控工具、磁盘配额的原理与配置、空间治理实战三个层面,带你构建一套可落地的存储治理方案。
一、容量监控:先看清磁盘到底用了多少
在动手做任何治理之前,首先要回答三个问题:哪个分区快满了?是哪些目录或文件占用的?空间是否被已删除但未释放的文件句柄占用?前两个问题由 df 和 du 两个经典命令回答,第三个问题则需要结合 lsof 来排查。
1. df:查看分区级容量
df 用于查看文件系统的整体使用情况,配合 -h 参数以人类可读的格式输出:
df -h
# 输出示例
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 49G 39G 7.9G 84% /
# /dev/sdb1 196G 140G 46G 76% /data
其中 Use% 是最关键的指标,一旦接近 90% 就需要重点关注。要排除临时文件系统(tmpfs、devtmpfs 等)的干扰,可以使用 -x 参数过滤:
df -h -x tmpfs -x devtmpfs -x overlay
2. du:定位空间占用源头
df 只能告诉你”分区满了”,du 才能告诉你”是谁占的”。逐层下钻是最常用的空间排查手法:
# 查看根目录下各一级目录占用(按大小排序)
sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20
# 定位当前目录下最大的 10 个文件
sudo du -ah /var/log 2>/dev/null | sort -hr | head -10
需要特别注意,df 与 du 的结果有时会出现明显差异,这通常意味着存在”已删除但被进程占用”的文件,下面会专门说明。
3. 已删除文件占用空间的经典陷阱
在 Linux 中,删除一个文件只是取消了目录项对它的引用,如果此时仍有进程打开着这个文件的句柄,磁盘块不会被真正释放。最常见的场景是:某个服务持续写日志,运维执行 rm 删除了日志文件,但服务进程没有重启,句柄依然持有,导致 df 显示空间没变而 du 查不到文件。
排查方法是用 lsof 找出被标记为 deleted 但仍被占用的文件:
sudo lsof +L1 | grep deleted
# 输出会列出 PID、进程名和文件路径
确认是日志文件后,可以通过清空而非删除来释放空间,或者让进程重新打开文件:
# 方法一:清空文件内容但不删除 inode(句柄仍然有效)
sudo truncate -s 0 /var/log/app.log
# 方法二:找到占用进程后优雅重启服务,使其释放句柄
sudo systemctl restart app-service
二、磁盘配额:从根源约束空间占用
容量监控是”事后发现”,磁盘配额才是”事前约束”。通过 quota 机制,管理员可以为每个用户或用户组设定空间上限与文件数量上限,当用户超过软限制时会收到警告,超过硬限制则直接被拒绝写入。
1. 安装与挂载参数准备
Ubuntu 上使用 quota 工具包,并通过挂载参数开启配额支持。先在目标分区上启用配额:
sudo apt update
sudo apt install -y quota
编辑 /etc/fstab,为需要启用配额的分区添加 usrquota 和 grpquota 挂载选项:
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data ext4 defaults,usrquota,grpquota 0 2
随后重新挂载并初始化配额数据库:
sudo mount -o remount /data
sudo quotacheck -cugm /data
sudo quotaon -v /data
quotacheck 的 -c 表示创建配额文件、-u 与 -g 分别处理用户与组、-m 允许在已挂载的分区上检查。
2. 为用户设定配额
使用 edquota 交互式编辑,或使用 setquota 命令行直接设定。假设用户 devuser 在 /data 分区的软限制为 4GB、硬限制为 5GB:
sudo setquota -u devuser 4194304 5242880 0 0 /data
上面四个数字依次是:块软限制(KB)、块硬限制(KB)、inode 软限制、inode 硬限制,这里将文件数量限制设为 0 表示不限制。查看配额使用情况:
sudo repquota -a
# 或针对单个用户
sudo quota -s devuser
3. 配额策略建议
软限制(soft limit)与硬限制(hard limit)之间应留有一定缓冲区间,同时配合宽限期(grace period)使用:
sudo edquota -t
# 设置宽限期,例如 blocks 宽限期为 7 天
这样用户超过软限制后仍可继续写入,但会收到警告并在宽限期后强制降到软限制以下,既给了缓冲又不会失控。对于共享型服务器,建议为每个开发用户分配独立配额,避免单个用户写满磁盘拖垮整个团队。
三、空间治理实战:一套可自动化的巡检脚本
只靠人工敲命令无法保证持续性,运维的最终目标是把”监控 + 预警 + 治理”固化成自动化流程。下面给出一个基于 shell 的容量巡检脚本骨架,可接入 cron 定时执行。
#!/bin/bash
# 磁盘容量巡检脚本:超过阈值时输出告警
THRESHOLD=85
LOG=/var/log/disk-check.log
check_partition() {
while read -r line; do
usage=$(echo "$line" | awk '{print $5}' | tr -d '%')
mount=$(echo "$line" | awk '{print $6}')
if [ "$usage" -ge "$THRESHOLD" ]; then
echo "[$(date '+%F %T')] WARN: $mount usage=$usage%" >> "$LOG"
fi
done < <(df -h -x tmpfs -x devtmpfs -x overlay | tail -n +2)
}
check_partition
将脚本加入 cron,每小时执行一次即可形成基础的容量预警能力:
0 * * * * /usr/local/bin/disk-check.sh
如果希望更完善的告警,可进一步接入 Prometheus 的 node_exporter 采集 node_filesystem_avail_bytes 指标,配合 Grafana 与 Alertmanager 实现可视化与多渠道通知,这部分会在后续监控告警专题中详细展开。
四、常见问题
Q1:df 显示 100% 但 du 统计不到大文件怎么办?
基本可以锁定是”已删除文件被进程占用”问题。使用 sudo lsof +L1 | grep deleted 定位进程,重启服务或 truncate 清空句柄对应的文件即可恢复。
Q2:配额设置后用户写入报 “Disk quota exceeded” 怎么办?
说明用户已触及硬限制或宽限期结束。用 repquota -a 查看占用详情,指导用户清理无用文件,或由管理员临时提高限额:sudo setquota -u user 新软限 新硬限 0 0 /data。
Q3:quotacheck 报错提示分区忙?
配额文件建立需要独占访问,可以先将分区以只读方式重新挂载,或进入单用户模式执行,也可以使用 -m 参数在已挂载状态下强行检查。
Q4:为什么删除了大文件,df 的可用空间没有立即变化?
删除文件后如果空间未释放,同样属于句柄占用问题;此外 ext4 的延迟分配机制也可能导致短暂的延迟,稍等片刻或用 sync 刷盘后再观察。
五、总结
存储治理的核心在于”防患于未然”:用 df 和 du 建立对容量的实时感知,用 lsof +L1 排查最隐蔽的句柄占用问题,再用磁盘配额从源头约束用户的资源占用,最后通过 cron 脚本或监控系统把这一切固化为自动化流程。这三层能力叠加起来,才能真正让磁盘从”最容易被忽视的隐患”变成”始终可控的资源”。
下期预告:第 17 天我们将进入数据备份与恢复专题,用 rsync、tar 与增量备份构建一套可演练、可恢复的数据保护体系,敬请期待。















暂无评论内容