磁盘配额这个话题,我印象里是那种“平时没人提,一提起来必是在救火”的Linux标配功能。无论是多用户服务器上某个人的家目录把/home塞满,还是日志分区被单个进程无限占满,Disk Quota 都是最直接的一道防线。这篇就聊清楚在 XFS 和 Ext4 两套文件系统上怎么真正把配额用起来,包括两类文件系统在实现机制上的差异、完整操作命令,以及我踩过的坑。
这不是一篇抄 man page 的翻译稿。文章里所有命令都是我在真实服务器上执行过的,尤其 XFS 的配额机制和 Ext4 完全两码事,用错工具轻则配额不生效,重则扫描直接卡死。适合所有被磁盘爆满问题困扰过的运维、做 NAS/网盘场景的技术人,以及正在备考 Linux 相关认证的朋友。
1. 动手前的准备:配额机制与文件系统差异
1.1 Ext4 与 XFS 的配额实现差异
先花三分钟把底层机制弄清楚,后面所有操作才不会迷糊。Ext4 走的是传统配额模型:配额信息放在文件系统根目录下的两个隐藏数据库文件里,分别是aquota.user和aquota.group。挂载时加上usrquota、grpquota选项后,内核读写块设备时会去查这两个账本,判断当前用户或用户组的空间消耗有没有越界。这种设计有年头了,管理工具很成熟,但代价是必须额外执行quotacheck来扫描并生成数据库文件,而且数据库和真实文件系统状态偶尔会不同步,需要定期重建。
XFS 从设计之初就把配额信息内嵌在文件系统的元数据里,换句话说,每个 inode 上直接就带配额计数,不需要外部数据库。挂载时用usrquota、grpquota、prjquota选项声明要启用哪些维度的配额,系统内部自动开始记账。这让 XFS 在三个地方明显胜过 Ext4:没有quotacheck这个前置步骤、配额计数和文件系统始终强一致、管理命令xfs_quota直接支持人类可读的单位(比如bsoft=20G),不需要把空间换算成块数。
注意:XFS 的配额有个组合限制——user quota 和 group quota 不能同时挂载,只能选择“用户+项目”或“组+项目”的组合。这和 Ext4 可以同时启用用户、组两类配额的习惯很不一样。
用生活化的语言来理解:Ext4 是小区门口放两本独立的登记簿,物业管理员(quota 工具)得定期把住户实际占用的空间重新抄录一遍;XFS 则是每家每户入住时直接在门牌上刻好了限额,保安一抬眼就知道这户超没超。
1.2 检查内核支持与安装工具
配额功能依赖内核的CONFIG_QUOTA选项,从 2.6 内核开始主流发行版默认都编译进去了。用下面这条命令确认:
grep CONFIG_QUOTA /boot/config-$(uname -r)输出里看到CONFIG_QUOTA=y就放心往下走。接着确认配额工具链已经装好。Debian/Ubuntu 系安装:
apt install quota -yRHEL/Rocky/AlmaLinux 系安装:
yum install quota -y安装包里的quota、quotacheck、edquota、repquota这些工具对应 Ext4 配额管理,而xfs_quota单独由xfsprogs提供,一般在装系统时就有了,没有就用yum install xfsprogs补上。
查看挂载点文件系统类型也不能跳过:
df -hT /home输出第二列是ext4还是xfs直接决定后面走哪条路。这一条一定要先查清楚,我见过不止一个同事明明要配 XFS 配额,却照着 Ext4 教程老老实实跑quotacheck,扫到一半直接卡住不动——因为 XFS 根目录根本不支持用那种方式创建数据库文件。
2. Ext4 文件系统启用配额全流程
2.1 修改挂载参数并重新挂载
假设要对/data这个 Ext4 分区启用用户和组配额,第一步是修改/etc/fstab。把原来的配置项改掉,在第四列加上配额参数:
/dev/sdb1 /data ext4 defaults,usrquota,grpquota 0 2这里usrquota和grpquota两个选项分别表示把用户和组维度的配额打开。如果只想限制用户,不加grpquota即可,避免不必要的记账开销。
修改完 fstab 后重新挂载:
mount -o remount,usrquota,grpquota /data用findmnt验证挂载选项是否生效:
findmnt -o OPTIONS /data看到usrquota和grpquota出现在输出里就说明内核已经按照配额模式挂载了这个分区。这里有个我踩过的坑:如果配额加在根分区/上,mount -o remount /有时候会因为进程占用导致失败,更稳妥的做法是直接把 fstab 改好之后重启系统,让内核在挂载时一路带好参数。
2.2 扫描并创建配额数据库
挂载参数就位后,先要生成配额数据库文件。这一步用quotacheck完成:
quotacheck -cugm /data参数拆开解释:-c表示创建新的配额数据库文件,-u扫描用户配额,-g扫描组配额,-m表示在服务在线状态下“静默”扫描,不强制把分区重新挂载为只读。如果你的服务可以停机维护,用-v加上详细输出会更直观:
quotacheck -cuvg /data命令跑完后在/data目录下会多出两个文件:
ls -l /data/aquota.user /data/aquota.group这两个文件的属主是 root,权限通常为 600,不推荐手动编辑。如果执行完ls发现文件不存在,大概率是挂载参数没生效,回顾 2.1 再排查一遍。
提示:
quotacheck在文件系统使用量很大的时候会扫描比较久,不要在中途强制 kill。扫描耗时主要取决于分区里的 inode 数量而非总容量,文件数量越多,扫描越慢。
2.3 用 edquota 与 setquota 设置用户限制
数据库建好之后激活配额并查看当前状态:
quotaon /data如果提示已经启用,不用慌张,这是正常现象——内核在检测到aquota.user存在且挂载带配额参数时,会自动打开配额强制执行。
设置单个用户的配额,交互式命令是:
edquota -u zhangsan /data执行后进入编辑器,界面大概长这样:
Disk quotas for user zhangsan (uid 1001): Filesystem blocks soft hard inodes soft hard /dev/sdb1 12340 20480 25600 1189 1000 1500我要重点解释这几列到底什么意思,因为十个人里有八个人第一次看会被绕进去。blocks列是用户当前已经占用的磁盘块数,单位是 1024 字节(1KB),所以12340就是大约 12MB。soft和hard就对应我们常说的“软限制”和“硬限制”。软限制是一个警告水位线:用户超过这个值后系统会开始警告,但依然允许继续写入;硬限制则是绝对红线,一旦触及,任何新的写入请求都会直接返回磁盘空间不足的错误。inodes列同理,限制的是文件数量而不是空间,对于像邮件存储、临时文件目录这种“文件数量比容量更容易爆”的场景,inode 限制往往比空间限制还重要。
如果不想进编辑器敲数值,用setquota一条命令搞定:
setquota -u zhangsan 20480 25600 1000 1500 /data四个数字分别对应:软块数、硬块数、软 inode 数、硬 inode 数,单位照旧是 1KB 块和“个”。我平时更习惯用setquota,因为可以把配置固化进自动化脚本里,不需要人来交互确认。
新用户批量设置配额时也别一个个敲,先设置一个模板账号,然后一键复制:
edquota -p template_user new_user1 new_user2宽限期(grace time)是另一个容易被忽略的细节。比如你给用户设了 20GB 软限制,他冲到 25GB 就触底硬限制,但中间那 5GB 能撑多久由宽限期说了算。默认是 7 天,超过宽限期后哪怕还没到硬限制也会直接拒写:
edquota -t /data3. XFS 文件系统启用配额全流程
3.1 挂载参数与配额类型选择
如果你面对的是 XFS 文件系统,整个过程要简单很多,但有几个前置规则必须讲清楚。XFS 的配额有用户、组、项目三个维度,分别对应挂载选项usrquota、grpquota、prjquota。注意一个关键限制:用户配额和组配额不能同时启用。你可以挂usrquota和prjquota的组合(用户维度配项目维度),或者grpquota和prjquota的组合,但就是不能usrquota和grpquota同时开。实际业务里我更常用的是“用户+项目”组合:既限制单个人能占据的空间,又能把一个共享协作目录的总容量圈死。
假设/srv是 XFS 分区,要在 fstab 里同时启用用户和项目配额:
/dev/sdc1 /srv xfs defaults,usrquota,prjquota 0 0重新挂载并验证:
mount -o remount,usrquota,prjquota /srv findmnt -o OPTIONS /srv看到输出中同时包含usrquota和prjquota就说明挂载成功。这一步之后,系统已经自动开始记账,不需要像 Ext4 那样跑任何扫描命令,也不需要手动quotaon——配额在挂载那一刻就已经处于强制状态了。
注意:传统的
quotaon、quotaoff、quotacheck命令在 XFS 上不可用,也不需要用。硬要去跑quotacheck,它不仅不会生成任何文件,还会让进程像死循环一样长时间挂在那里。
3.2 用 xfs_quota 设置空间与 inode 限制
XFS 配额的官方管理命令是xfs_quota,用-x进入专家模式才能执行修改类操作。先看当前各用户的配额和用量:
xfs_quota -x -c 'report -u -h' /srv-h参数会把数字格式化成易读的单位,输出里直接能看到20G、25G这样的数值,比 Ext4 那一串裸块数友好太多。给指定用户设置空间软硬限制:
xfs_quota -x -c 'limit -u bsoft=20G bhard=25G zhangsan' /srvbsoft是空间软限制,bhard是空间硬限制。如果要限制文件数量,把b换成i就行:
xfs_quota -x -c 'limit -u isoft=10000 ihard=12000 zhangsan' /srv设置宽限期:
xfs_quota -x -c 'timer -u -b 7days' /srv这里的-b表示对块(空间)宽限期生效,7days的意思和 Ext4 默认宽限期一致。查看单用户状态用quota -u依然能看,但完整报表建议统一用xfs_quota -x -c 'report -h -u'。
顺带一提,体验上 XFS 比 Ext4 舒服的一个点:限制值直接写单位,完全不用心算“多少 KB 等于 20G”,也不存在文件系统块大小换算的问题。命令输出直观,排查问题时一眼就能定位谁超过了配额。
3.3 Project 配额的实际用法
Project 配额(项目配额)是 XFS 真正拉开和 Ext4 差距的功能,强烈建议认真看这一段。适用场景很典型:某个共享目录比如/srv/web,里面全是不同用户创建的文件,你想限制的是“整个目录总量不能超过 20G”,而不是单独限制某个人。按传统思路只能挨个给每个用户设配额,既繁琐又不可控,项目配额就是专门解决这个问题的。
启用项目配额需要三要素。第一,挂载时带prjquota(3.1 已做);第二,编辑/etc/projects文件,定义项目 ID 对应的路径:
100:/srv/web第三,在/etc/projid文件里给项目起个好记的名字:
web:100然后给目录打上项目标记并初始化:
xfs_quota -x -c 'project -s web' /srv这条命令会扫描/srv/web下的所有文件,给每个 inode 盖上项目编号的印章。盖完章才能设置配额:
xfs_quota -x -c 'limit -p bsoft=18G bhard=20G web' /srv查看项目配额报表:
xfs_quota -x -c 'report -p -h' /srv这里有一个特别容易翻车的点:项目配额只对打了项目标记的文件生效,目录下新建的文件不会自动继承父目录的项目标记。所以初始化之后,新写入的文件还需要重新跑一次project -s才能确保它们也被计入项目配额。我在生产上遇到过一个诡异现象:目录明明设置了 20G 硬限制,但实际文件总是能越写越大,最后排查出来 80% 的原因都是新增文件没有及时打标记。自动化场景可以通过在创建文件的流程后面挂一条xfs_quota -x -c 'project -s web'来兜底。
4. 配额管理、维护与自动化
4.1 日常管理命令速查
配额配好只是开始,日后的查看、调整、排查才占运维工作的大头。我把常用命令按用途整理成一张速查表,区分了 Ext4 和 XFS 的适用性:
| 操作场景 | Ext4 命令 | XFS 命令 |
|---|---|---|
| 查看所有用户配额报表 | repquota -a | xfs_quota -x -c 'report -u -h' |
| 查看单个用户配额 | quota -u zhangsan | quota -u zhangsan |
| 设置用户空间限制 | edquota -u zhangsan或setquota -u | xfs_quota -x -c 'limit -u bsoft=.. bhard=..' |
| 设置组限制 | edquota -g或setquota -g | xfs_quota -x -c 'limit -g bsoft=.. bhard=..' |
| 启用/禁用配额 | quotaon / quotaoff | 不需要,挂载即生效 |
| 扫描重建数据库 | quotacheck -cug | 不需要 |
repquota -a在 Ext4 上非常好用,它会列出所有已启用配额的文件系统上每个用户的用量、限制和宽限状态。我的习惯是每天早上拉一次报表盯用量趋势,而不是等磁盘告警邮件炸了再去看。
4.2 告警与清理策略经验
配额设多少合适,没有标准答案,但我可以分享一套实战配置逻辑。典型的 Web 共享目录,业务方说“每个人给 20G 就行”,不要真的只写死 20G/20G。我的做法是软限制 16G、硬限制 20G、宽限期 7 天。这样用户在软硬限制之间那段空间里会感受到压力,有缓冲时间去清理自己的文件,而 7 天的宽限期足够覆盖大多数“忘了删文件”的拖延症场景,也不会让磁盘真的被撑死。
inode 限制容易被漏掉,但它在两类场景里极其关键:一是邮件服务,海量小文件会瞬间把 inode 耗尽;二是程序生成的临时缓存。空间限额设到 20G,结果 1000 万个小文件把 inode 爆了,整个分区报“No space left on device”,这种问题不看 inode 根本想不到。
清理动作上,先定位谁占了大头:
du -h --max-depth=1 /home | sort -hr | head -20配合lsof +L1还能找出那些已经删除但仍被进程占用的“隐形文件”,这类文件不释放空间,重启对应的进程服务通常就能收回。
4.3 脚本化提升效率
新用户开通配额的场景可以直接做成脚本,一条命令完成用户创建和配额分配:
useradd zhangsan setquota -u zhangsan 20480 25600 1000 1500 /home模板复制的方式前面提过,但脚本里更推荐用setquota,参数一目了然。定期报表可以配合 crontab 实现:
0 8 * * * /usr/sbin/repquota -a | mail -s "Daily Quota Report" ops@example.com扩展需求更丰富时,把repquota输出解析成 CSV 再推到监控系统里,就能在 Grafana 上画出每个用户的配额用量曲线,提前发现问题。
5. 常见坑与排查实录
5.1 quotacheck 报错且 aquota 文件缺失
新人在 Ext4 上最常遇到的错误:执行quotaon /data时提示找不到配额文件。核心原因就一个——挂载时没有带配额参数,或者quotacheck扫描没有真正成功。排查顺序如下:
findmnt -o OPTIONS /data确认输出里包含usrquota。如果没有,重新挂载并回头检查 fstab 格式。如果挂载参数正确但aquota.user依然没生成,尝试手动执行一次强制扫描:
quotacheck -cfu /data还是不行,就umount /data后跑一次:
quotacheck -cuv /data注意在卸载状态下扫描更干净,不会受在线进程的瞬时写操作干扰。
5.2 XFS 配额重启后失效
XFS 在启动阶段最容易出问题的场景是给根分区启用配额。很多朋友在 fstab 里给/加上usrquota,重启后findmnt /一看,选项里根本没有配额参数。这是因为根文件系统的挂载时机和参数传递方式特殊,fstab 里的选项被内核 cmdline 的rootflags接管了。解决办法是编辑 GRUB 内核启动参数:
rootflags=usrquota,prjquota改完执行update-grub或grub2-mkconfig重新生成引导配置,再重启验证。非根分区则通常只需要 fstab 配置正确就足够。
5.3 软限制不告警、硬限制被绕过
两个经典误区。第一,软限制超限之后系统默认只在内核层面拒绝写入,并不会主动发邮件提醒用户。告警依赖warnquota服务,需要配置/etc/warnquota.conf并确保邮件系统能正常工作。如果环境里根本没有配置 MTA,那不管怎么超限都不会有邮件出来,这不是配额没生效,是告警通道没打通。
第二,root 用户对配额有豁免权。很多新手用 root 往目录里dd大量数据,发现怎么都突破硬限制,于是以为配额是假的。实际情况是拥有CAP_SYS_RESOURCE权限的 root 可以超出硬限制。验证配额是否生效,务必用普通用户身份测试:
sudo -u zhangsan dd if=/dev/zero of=/data/test.img bs=1M count=30000另外还要注意文件属主变化对配额的影响:chown操作会把文件占用的空间从原属主的配额里转移到新属主身上,多人协作目录里如果出现“某用户配额莫名暴涨”的情况,先查有没有批量 chown 脚本在背后搞事。
最后说一点个人体会。给文件系统开配额这事,技术难度不高,真正考人的是对业务的理解——软硬限制的间距、宽限期的长短、inode 限制要不要设、项目配额该用于哪些目录,每个决定背后都是业务场景和运维容量的权衡。我自己的经验是先在测试机上完整模拟一遍,特别是 XFS 项目配额要确认标记能及时打上,再上线生产。磁盘配额只是最后一道防线,事后的告警、清理和容量规划同样不能省。