磁盘配额
多人共用的服务器上,磁盘是典型的"公地悲剧"资源:某个人跑了个失控的日志任务,或者 ~/.cache 被无意中塞满,/home 分区一到 100%,所有人的 SSH 登录都会开始报 No space left on device——即使他们各自的家目录还有大把空闲。磁盘配额(disk quota)就是为这种场景设计的硬性预算:给每个用户(或每个组)设定用量上限,让失控的那一个先撞墙,而不是拖垮所有人。启用配额后,系统会在写入路径上实时统计每个 UID/GID 占用的数据块与 inode 数,一旦超过阈值就直接拒绝写入并返回错误。本页先讲清楚软限制与硬限制这对核心概念(以及"宽限期"这个容易被误解的中间态),再分别给出 ext4 与 XFS 的启用流程——两者初始化方式差异不小,照抄对方的步骤一定失败。
内容参考自 Arch Wiki、鸟哥的私房菜与各发行版
man手册,见文末参考资料。
学习目标
- 说清配额防的是什么问题,以及它统计的两类资源(块与 inode)
- 区分软限制(soft,可暂时超过)与硬限制(hard,绝对上限)的语义
- 分别完成 ext4 与 XFS 的配额启用与初始化
- 会用
edquota设置、repquota审计、edquota -p批量套用
1. 为什么需要配额
没有配额的共享 /home 等于把整块分区的命运交给运气。常见触发场景:
- 一名用户在
~/Downloads下载了 80 GB 数据集,分区瞬间告急; - 某个服务账号(比如跑批处理的
etl用户)日志没轮转,单账号写满几十 GB; - 部署脚本用
nohup ... > ~/job.out跑长任务,输出文件无人清理。
配额把"整盘预算"细化为"每人预算",并且能在告警阶段(超过软限制但未达硬限制)就通过邮件/日志提醒,给管理员留出处置时间。需要注意的是,配额统计的是文件系统层的用量:硬链接算一次(因为指向同一 inode),稀疏文件按实际占用块算;它不感知"这个文件是否重要",只看字节数与文件个数。
另一类容易混淆的资源是 inode。文件系统格式化时就固定了 inode 总数,每个小文件都要消耗一个 inode。哪怕磁盘还有 100 GB 空闲,只要 inode 耗尽(典型场景:百万个几 KB 的小缓存文件),写入同样会失败。因此配额要同时限制块(KB)和 inode(文件数)两类指标。
2. 软限制、硬限制与宽限期
edquota 编辑的每一行都包含四个数字,语义必须先分清,否则设出来的限制一定不符合预期:
| 限制类型 | 含义 | 超限后的行为 |
|---|---|---|
| soft(软) | 允许日常使用的额度 | 可以暂时超过,但进入宽限期倒计时 |
| hard(hard) | 绝对上限 | 写入被内核直接拒绝,无法突破 |
| inodes soft | 最多能创建多少个文件 | 同块 soft,超限进入宽限期 |
| inodes hard | 文件数的绝对上限 | 达到后 creat/open(O_CREAT) 失败 |
宽限期(grace period)默认 7 天。一旦用量超过 soft 但未达 hard,系统开始计时;宽限期内可以继续写,超时后 soft 的效果等同于 hard,写入开始被拒绝,直到用量降回 soft 以下。这个设计的用意是容忍突发:平时写到 800 MB 无妨,只要在一周内清掉,就不会被卡死。把 soft 设为 0 表示"不设软限制,只用 hard";hard 必须 ≥ soft,否则 edquota 保存时会拒绝。
$ sudo edquota -u alice
Filesystem blocks soft hard inodes soft hard
/dev/sda2 1048576 2097152 3145728 842 0 0表格数值单位是文件系统块(通常 1 块 = 1 KB),从左到右依次是已用块、块 soft、块 hard、已用文件数、inode soft、inode hard。blocks 已用量由内核实时统计写入,不包含你手工 dd 到块设备绕过文件系统的情况;改完配额数值立即生效,无需重启服务。
3. 启用配额:ext4(Debian/Ubuntu、Arch、Rocky 默认)
ext4 的配额靠内核在挂载时读取 usrquota/grpquota 选项启用,流程分三步:改挂载选项 → 重新挂载 → 运行 quotacheck 建库。顺序不能颠倒——quotacheck 需要在已启用配额的挂载点上扫描并创建 aquota.user/aquota.group 数据库文件,没先 remount 就执行会直接报错。三系安装工具包的命令不同(apt install quota、pacman -S quota-tools、dnf install quota),但之后的流程完全一致:
$ sudo vim /etc/fstab
/dev/sda2 /home ext4 defaults,usrquota,grpquota 0 2
$ sudo mount -o remount /home
$ mount | grep /home
/dev/sda2 on /home type ext4 (rw,relatime,usrquota,grpquota)
$ sudo quotacheck -cugm /home # -c 创建数据库 -u 用户 -g 组 -m 禁止只读检查
$ sudo quotaon /home
$ sudo systemctl enable quotaon.service # systemd 系发行版通用,实现开机自动开启4. 启用配额:XFS(只认挂载选项,没有 quotacheck)
XFS 的实现与 ext4 不兼容:它不在挂载点生成 aquota.* 文件,而是把配额元数据存在文件系统内部的隐藏 inode 中,因此没有 quotacheck 这一步,初始化靠 xfs_quota 命令。如果照抄第 3 节的步骤去跑 quotacheck,会得到 quotacheck: Cannot find filesystem to check 之类的失败——这是 ext4/XFS 混淆最经典的结果。
$ sudo vim /etc/fstab
/dev/sdb1 /data xfs defaults,quota,usrquota,grpquota,prjquota 0 0
$ sudo mount -o remount /data
$ sudo xfs_quota -x -c 'limit -u alice 20g 30g' /data # 软 20g,硬 30g,语法与 edquota 不同
$ sudo xfs_quota -x -c 'report -h' /dataFedora/RHEL 系允许同时存在 XFS 与 ext4 分区,但同一分区只能用一套配额工具——按 df -T 先确认文件系统类型,再决定走第 3 节还是第 4 节。RHEL/CentOS/Rocky 默认根与 /home 常为 XFS,Debian/Ubuntu 与 Arch 默认 ext4,这也是"教程不标发行版就会翻车"的典型例子。
5. 查看与审计
$ quota # 当前登录用户查自己(无需 root),-s 以 GB/MB 显示
Disk quotas for user alice (uid 1000):
$ sudo quota -u alice # 管理员查任意用户
$ sudo repquota /home # 一次性审计整个挂载点,适合写进巡检脚本
*** Report for user quotas on /dev/sda2
alice 3145728 2097152 1048576 ...repquota 输出的列依次是 hard、soft、已用量;grace 列出现倒计时(如 6days+)就意味着该用户已超软限制、正在宽限期内,是发提醒邮件的最佳时机。生产环境通常配合 cron 每天跑一次 repquota -ugs 并 diff 阈值。
6. 批量设置与复制
逐个 edquota 低效且容易输错,模板复制是批量初始化的正确姿势:先给一个"标准用户"调好配额存为模板,再用 -p(prototype)复制给多人;也可以按组套用。
$ sudo edquota -u template_user
$ sudo edquota -p template_user alice bob carol dave
$ sudo edquota -g -p template_group developers需要临时解锁某人(比如应急导出数据)时,把他的 soft/hard 都临时调大,操作完成后立刻改回原值——不要图省事直接 quotaoff /home 关闭整个文件系统的配额,那会让所有人的限制同时失效,审计日志也会缺失这段"谁突破了额度"的记录。
7. 常见坑
改了 fstab 却忘了 remount。
usrquota选项只在挂载时被读取,quotacheck对未启用配额的挂载点会失败。顺序永远是:改 fstab →mount -o remount→quotacheck→quotaon。在 XFS 上跑 ext4 的流程。XFS 没有
quotacheck/aquota.user,改用xfs_quota(见第 4 节)。反之在 ext4 上用xfs_quota也无效。把 soft 当成"警告值"就不管 hard。soft 超限只是开始计时,真正卡住用户的是 hard。给共享服务器设值时的经验比例是 soft ≈ 70% hard,给 7 天宽限留出回收窗口。
忽略 inode 限制。只设了块限额的目录,仍可能被百万小文件塞爆 inode。对日志/缓存目录,把 inodes soft 也设上(比如 50 万),双保险。
在 NFS 上误用本地配额。NFS 客户端的配额统计依赖服务器端的
usrquota挂载与quota服务;只在客户端quotaon是无效的。共享存储配额要在导出端配置。删除用户后残留配额记录。
userdel -r不会自动清理aquota.user里的条目。长期运行的机器定期用repquota /home对比实际用户列表,或用edquota -d username(若发行版支持)清理孤儿条目。
参考资料
- Arch Wiki - Disk quota — wiki.archlinux.org
- 鸟哥的私房菜 - 磁盘配额 — linux.vbird.org
- XFS 配额管理官方文档 — xfs.org
- Debian 手册 - 磁盘配额 — debian.org
- RHEL 9 - 配置配额 — docs.redhat.com
man quota、man repquota、man edquota、man quotacheck、man quotaon、man xfs_quota