☰
Linux磁盘配额实战:XFS与Ext4的用户和目录限额配置指南
2026/10/3 9:03:26 网站建设 项目流程

最近在巡检一台多用户开发服务器的存储时,发现/data分区直接满了 100%。顺手查了一下占用排行,最大的一个普通用户的 home 目录吃了 1.2TB,而这块盘总共才 1.5TB。更麻烦的是,同一个物理卷上还跑着 Jenkins 的构建任务和数据库备份脚本,盘一满,整个 CI 链路全崩了。这种"一颗老鼠屎坏一锅汤"的场景,就是 Disk Quota 存在的意义。在 Linux 系统里,XFS 和 Ext4 是最常见的两种本地文件系统,启用手配额的方式有相通之处,也有各自的脾气。这篇文章按我实际操作的顺序,把 XFS 和 Ext4 的配额启用过程、常用命令和踩坑点完整过一遍,适合正在管理多用户服务器、共享存储目录,或者打算给目录做容量上限的运维同学参考。

1. 磁盘配额不是"限速",而是给每个用户的磁盘空间装上闸门

1.1 配额解决什么问题

很多人第一次接触 Disk Quota 时,会把配额理解成"限制某块盘的读写带宽",其实完全不是一回事。磁盘配额限制的不是速度,而是空间占用总量。类比一下:小区停车场每个车位都有一个固定大小,你停一辆车没问题,但你要是把自己的车、老婆的车、亲戚的车全停进去,物业就得管了。配额就是物业给每个住户画的"最多能停几辆车"的红线。

实际运维中,配额最典型的场景有三个:

  • 多用户开发服务器:几十个开发人员的 home 目录放在同一个物理分区上,没人管的话,随便一个同事的构建产物就能把盘塞满,其他人全部遭殃,连登录都费劲。
  • 共享上传目录 / NAS 挂载目录:用户上传大文件,或者程序跑出异常日志循环写盘,导致共享目录空间耗尽。
  • 临时目录和备份目录:/tmp、备份脚本的输出目录如果不设上限,一次写满之后,连系统日志都写不进去。

这三类场景的共同点是:你没法信任"所有人都自觉"这条假设。配额就是那个不用说话就能强制执行的空间管理员。

1.2 软限制、硬限制与宽限期

Linux 配额体系中,每个配额维度(用户、组、项目)都可以设置两个数值:软限制(soft limit)和硬限制(hard limit),单位默认是 KB,但在 XFS 的xfs_quota里可以直接写 5m、5g 这种人类可读单位。

这两者的区别,我用一句话概括:软限制是"警告线",硬限制是"闸门"。

  • 当用户占用量超过软限制但没有超过硬限制时,系统仍然允许继续写入,但会在用户每次登录或者执行quota命令时给出超过限额的警告。如果你设置了宽限期(grace period),那么超过软限制后还有一个倒计时,比如 7 天。
  • 当用户占用量达到硬限制,或者超过了软限制且在宽限期内没有清理,系统就会直接拒绝写入,返回 Disk quota exceeded 错误。
  • 宽限期只对软限制有效,对硬限制来说没有"商量余地"。

举个例子:我给某个用户设置软限制 5GB、硬限制 6GB、宽限期 7 天。用户在写了 5GB 之后开始收到警告,但他还是能继续写,最多写到 6GB。如果在 7 天宽限期结束后仍然高于 5GB,那么 6GB 这个硬限制才会真正生效,此刻哪怕只写一个文件也会被拒绝。硬限制是"绝对上限",一般不会因为宽限期而改变。

1.3 为什么选择 XFS 或 Ext4 作为配额落地方案

很多云服务器默认文件系统就是 Ext4,传统数据库服务器、NFS 服务端也大量用它;而 XFS 在 RHEL/Rocky 等系统上被选为默认文件系统,尤其适合大容量存储和大量小文件的并发写场景。配额这块,两者各有各的玩法,先看下表:

对比项Ext4XFS
配额数据库独立配额文件:aquota.user / aquota.group无独立文件,配额信息由文件系统自身维护
首次启用需要 quotacheck 扫描生成配额文件挂载选项加上后自动跟踪,无需扫描
用户/组配额挂载选项usrquota, grpquotauquota, gquota(也兼容 usrquota/grpquota 写法)
项目配额挂载选项prjquota(内核 4.5+,配置较繁琐)pquota / prjquota,原生支持
管理命令quotaon / quotaoff / edquota / setquota / repquotaxfs_quota 一站式管理
在线关闭quotaoff 即可xfs_quota -x -c 'off -u' 或 remount

我的建议是:如果是管理老设备上的 Ext4 分区,按传统方式走 quotacheck + quotaon;如果是新装生产服务器且明确要做目录级限额,优先把该分区格式化成 XFS,用项目配额一步到位。

2. 动手前:先把文件系统类型和挂载状态看清楚

2.1 确认文件系统类型和当前挂载状态

很多人上来直接改/etc/fstab,结果 remount 报错,根源就是搞错了文件系统类型。开始操作前,至少用下面三条命令确认现状:

lsblk -f df -hT blkid /dev/sdb1

lsblk -f能列出每个分区的文件系统类型和 UUID;df -hT能看到当前挂载点用的文件系统以及已用空间;blkid拿到分区的具体 UUID 和设备路径,后面写 fstab 时要用。

这里有个容易忽略的点:如果分区已经挂载,且当前使用量接近 100%,启用配额后历史文件也会立刻被计入占用。比如某个用户已经用了 7GB,你给他设置硬限制 6GB,那配额一生效,他马上写不进任何文件,还会一脸懵。所以配额上限的设定要充分考虑存量占用,别只看"以后"。

2.2 修改 /etc/fstab 挂载选项的正确姿势

无论 Ext4 还是 XFS,最稳定的方式都是先把配额挂载选项写进/etc/fstab,然后 remount。直接改 fstab 的好处是重启后配额不会"消失",对服务器这种常年不关机但最怕重启后配置丢失的场景来说,这是基本要求。

Ext4 的 fstab 写法:

UUID=3d5a1234-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data ext4 defaults,usrquota,grpquota 1 2

XFS 的 fstab 写法:

UUID=ab987654-xxxx-xxxx-xxxx-xxxxxxxxxxxx /srv/data xfs defaults,uquota,gquota 0 0

注意两个细节:

  • Ext4 的 fstab 最后两列是 dump 和 fsck 检查顺序,保持原来的值即可,一般不因为加配额就改动。
  • XFS 的 dump 和 fsck 字段固定写 0 0,因为 XFS 不需要也不支持传统 fsck 顺序检查,这个别照抄 Ext4 的写法。
  • 如果不希望用 UUID,也可以写/dev/sdb1 /data ext4 defaults,usrquota,grpquota 1 2,但生产环境建议优先 UUID,避免内核识别盘符顺序变化后挂错设备。

提示:修改/etc/fstab之前,先备份一份:cp /etc/fstab /etc/fstab.bak.$(date +%F)。改完后用mount -a做一次语法验证,确认没有拼写错误,再执行 remount。

2.3 操作前的安全检查清单

以下几件事我每次都会做,省掉任何一步都可能演变成事故:

  1. 确认分区不是根分区/。在根分区上启用配额不是不行,但一旦软限制或硬限制设置失误,可能会影响系统本身写日志、写临时文件,甚至导致服务起不来。第一次试验建议挑独立挂载点。
  2. 确认当前空间余量充足。quotacheck 在 Ext4 上需要额外空间写配额文件,虽然 aquota.user 通常只有几 KB,但如果盘已 100% 满,扫描过程可能出现异常;XFS 无此问题但也要留操作余量。
  3. 确认要限制的用户名单。配额是按 UID/GID 或项目 ID 计数的,不是按目录计数的。你如果想要"某个目录最多放多少",那属于项目配额,普通用户配额不适用。
  4. 开通 SSH 带外管理。万一配额设置过于激进把用户锁死,你需要能用 root 登进去改,别把自己也挡在外面。

3. Ext4 配额全流程:quotacheck、quotaon 与 edquota 的组合拳

3.1 修改挂载参数并重新挂载分区

假设 Ext4 分区/dev/sdb1挂载在/data,我已经把/etc/fstab改成了带usrquota,grpquota的配置。接下来执行:

mount -o remount /data

然后确认配额选项是否真正生效:

mount | grep "/data " cat /proc/mounts | grep "/data "

如果/proc/mounts里能看到usrquota,grpquota,说明挂载选项加载成功。这里有个坑:有些发行版或容器环境里,单纯执行mount -o remount /data时 fstab 中新增的选项不一定被重新解析,保险做法是显式指定:

mount -o remount,usrquota,grpquota /dev/sdb1 /data

如果分区当前正在被大量进程使用,remount 不会中断读写,这个不用担心。但如果你在/etc/fstab里的挂载选项跟之前的差异过大,比如改动了 ro/rw、acl 等,remount 有可能失败,此时不要强行卸载重挂,先回滚 fstab 再排查。

3.2 初始化配额数据库:quotacheck 的细节与误区

Ext4 启用配额前,需要扫描整个文件系统,把所有已存在文件归属到各用户/组,生成配额统计数据库。这一步是 Ext4 和 XFS 最明显的分水岭。

首次启用执行:

quotacheck -cug /data

参数含义:-c创建全新的配额文件,-u启用用户配额,-g启用组配额。执行成功后,/data目录下会出现aquota.user和aquota.group两个文件。

这一步常见的问题有三个:

  • 报错Cannot get quotafile name。原因通常是配额文件已经存在但文件系统没有正确加载配额选项,或者配额文件是从别的机器拷贝过来的脏数据。解决办法:先确认挂载选项没问题,必要时删除/data/aquota.user和/data/aquota.group再重新创建。
  • 扫描速度极慢。如果分区上有几百万个小文件,quotacheck 可能要跑十几分钟甚至更久。期间不要重启机器,也不要手动 kill 进程,等它自然结束。
  • 重复扫描时给配额"加了新档案"。第二次执行不需要-c了,直接quotacheck -ug /data即可更新统计;但如果配额文件损坏,重新-c也没问题,最多重新生成一遍数据库。

扫描完成后,正式启用配额:

quotaon /data quotaon -p /data # 查看配额是否处于开启状态

quotaon -p如果显示user quota on /data is on和group quota on /data is on,就说明配额已经进入工作状态。现代主流发行版在 fstab 配置好usrquota并重启后,会自动执行 quotaon,不需要额外写开机脚本;但如果是精简版系统或容器环境,建议自己确认一遍。

3.3 用 edquota 和 setquota 下发配额策略

开启配额后,要给具体用户或者组设置上限。最直观的方式是edquota,它会打开一个编辑器让你手动改:

edquota -u zhangsan

编辑界面大概是这样的:

Disk quotas for user zhangsan (uid 1001): Filesystem blocks soft hard inodes soft hard /dev/sdb1 220 5120000 6144000 7 0 0

文件里单位是 KB,blocks表示当前已用块数,soft和hard列分别对应软限制和硬限制。这里5120000KB 等于 5GB,6144000KB 等于 6GB。改完保存退出即可。

命令行批量下发更推荐setquota,尤其适合脚本化操作:

setquota -u zhangsan 5120000 6144000 0 0 /data

这里的四个数字依次是:用户软限制(KB)、用户硬限制(KB)、inode 软限制、inode 硬限制。inode 限制一般不要轻易设,因为那会限制文件数量,很多程序会创建大量临时文件,inode 设得太低会莫名报错,我一般写 0 表示不限制。

组配额方式完全一样:

setquota -g devteam 20480000 25600000 0 0 /data edquota -g devteam

3.4 验证配额是否真正生效

设置完配额,一定要做一次超额写入测试,别等到线上用户写不进去才发现问题。从普通用户身份写一个超出硬限制的文件:

su - zhangsan -c "dd if=/dev/zero of=/data/zhangsan/test.img bs=1M count=7000"

如果配额生效,dd 在写到接近 6GB 时会报错:dd: error writing '/data/zhangsan/test.img': Disk quota exceeded,并且ls -lh看到文件大小稳定在硬限制附近。

另外可以用quota命令从用户视角查看状态:

quota -u zhangsan

输出里如果看到*标记,说明当前已经超过软限制,需要留意宽限期。

4. XFS 配额全流程:xfs_quota 的一站式管理

4.1 挂载选项和 XFS 配额机制说明

XFS 启用配额的方式,比 Ext4 少了一个"数据库初始化"环节。因为 XFS 文件系统自身就维护每个用户、组的空间统计信息,挂载选项加持后,系统会实时跟踪文件占用,不需要像 quotacheck 那样扫描整个盘生成外部文件。这在大容量存储场景里是一个很实际的优势——真正的"挂上即用"。

先改/etc/fstab:

UUID=ab987654-xxxx-xxxx-xxxx-xxxxxxxxxxxx /srv/data xfs defaults,uquota,gquota 0 0

然后重新挂载:

mount -o remount /srv/data

同样确认挂载选项生效:

cat /proc/mounts | grep "/srv/data "

如果没生效,可以显式指定:

mount -o remount,uquota,gquota /srv/data

XFS 的挂载选项既支持uquota, gquota短写法,也支持usrquota, grpquota长写法,两者等价。项目配额对应的选项是prjquota,可以单独使用也可以跟用户/组配额一起使用。

4.2 xfs_quota 命令体系解析

XFS 配额管理统一用xfs_quota命令。管理员操作必须加-x(专家模式),-c指定命令,最后跟挂载点。下面是我常用的几个命令。

查看配额报告:

xfs_quota -x -c 'report -h' /srv/data

-h让容量以人类可读的 GB/MB 显示。输出会分用户、组、项目几个维度显示used、soft、hard、grace。

给指定用户设置配额:

xfs_quota -x -c 'limit -u bsoft=5g bhard=6g zhangsan' /srv/data

这个写法的好处是直接支持5g、600m这种单位,不用自己做 KB 换算。bsoft是空间软限制,bhard是空间硬限制,对应的 inode 限制是isoft和ihard。

设置组配额:

xfs_quota -x -c 'limit -g bsoft=20g bhard=25g devteam' /srv/data

设置宽限期:

xfs_quota -x -c 'timer -u -b 7days' /srv/data

查看单个用户当前占用:

xfs_quota -x -c 'quota -h -u zhangsan' /srv/data

禁用配额时可以使用:

xfs_quota -x -c 'off -u' /srv/data

不过这个命令只是关闭用户配额记账,挂载选项还保留着,重启后又会自动打开。如果想彻底移除配额,还是改掉/etc/fstab里的选项后 remount 最干净。

4.3 XFS 项目配额:按目录限额的进阶玩法

XFS 的项目配额是我最推荐的功能,它解决的是"不按用户、按目录限额"的需求。比如/srv/data/web下要放多个网站的静态资源,你希望整个 web 目录最多占用 20GB,不管里面是哪个用户写的。

项目配额配置分为三步。

第一步,在/etc/projects里给目录分配一个项目 ID:

echo "200:/srv/data/web" >> /etc/projects

第二步,在/etc/projid里给项目 ID 起一个名字:

echo "web:200" >> /etc/projid

第三步,初始化项目目录:

xfs_quota -x -c 'project -s web' /srv/data

执行后,/srv/data/web目录会被打上项目 ID 200 的标记,之后新建在里面的文件和子目录会自动继承这个项目 ID。然后设置项目配额:

xfs_quota -x -c 'limit -p bsoft=18g bhard=20g web' /srv/data

查看项目维度的报告:

xfs_quota -x -c 'report -p -h' /srv/data

项目配额最大的好处是天然支持"多用户共享同一个目录预算":某个项目目录下有 5 个人在写文件,配额总量按项目算,而不是按每个人算。这在多租户应用的服务器上非常实用。

提示:Ext4 在内核 4.5 之后也支持项目配额,但我实际用过之后感觉配置门槛偏高,同一块盘上有多个项目时更容易混,所以如果明确要做目录级配额,我会直接把分区做成 XFS,省事也少踩坑。

5. 配额启用后的日常巡检与动态调整

5.1 定时巡检:repquota 与 xfs_quota report 的监控脚本

配额不是设置完就能撒手不管的。用户数量多了,总有人会冲到软限制附近,你不主动巡检,最后一定会有人在周五晚上把盘写满。

Ext4 查看所有用户配额使用情况:

repquota -a repquota -v /data

XFS 查看完整报告:

xfs_quota -x -c 'report -h' /srv/data xfs_quota -x -c 'report -hu' /srv/data # 只看用户 xfs_quota -x -c 'report -hg' /srv/data # 只看组

我习惯写一个简单的巡检脚本,每天通过 cron 跑一次,把超过软限制的用户发出来。脚本核心逻辑不复杂:

repquota -a | awk '$4 ~ /[0-9]+/ && $4 > 0 {print $1, $2, $4}'

对于 XFS,报告输出更适合用sort配合awk筛选。核心思想一样:把used接近或超过soft的行挑出来,交给告警渠道。

5.2 配额满了之后,用户会看到什么

配额的强制效果在普通用户视角里非常直观:执行写入命令,shell 返回Disk quota exceeded。但对程序来说,这可能表现为很隐蔽的失败——比如数据库写入事务中断、日志服务停止写入但不退出、文件上传接口报 500。

所以配额的硬限制设置不能拍脑袋。如果用户跑的是一个真实业务,建议先观察一周使用曲线,再定软硬限制;软限制可以定在"预期正常使用量的 120%",硬限制定在"软限制的 120%",这样既留缓冲,又不会让业务突然哑火。

5.3 关闭配额的完整过程

有时候业务调整不需要配额了,或者要格式化分区重新规划,这时关闭配额也要干净利落。

Ext4 关闭配额:

quotaoff /data

然后删掉配额文件:

rm -f /data/aquota.user /data/aquota.group

最后把/etc/fstab里的usrquota,grpquota字段去掉,mount -o remount /data即可。

XFS 关闭配额:

xfs_quota -x -c 'off -u' /srv/data xfs_quota -x -c 'off -g' /srv/data

再把 fstab 的uquota,gquota,prjquota去掉,mount -o remount /srv/data。相比 Ext4,XFS 没有独立配额文件可删,重置配额统计直接xfs_quota -x -c 'limit -u bsoft=0 bhard=0 zhangsan' /srv/data就行。

6. 生产环境踩坑总结:几个真正值钱的细节

6.1 Ext4 的 quotacheck 在已满分区上的表现

我在一台老服务器上遇到过这样的问题:分区使用率 100%,有告警说要启用配额给用户限流。当时执行quotacheck -cug /data时直接卡住,后来清理出少量空间再跑就正常了。原因推测是 quotacheck 需要在文件系统内创建 quota 文件,哪怕只有几 KB,也需要文件系统有一定可用空间来分配 inode。

面对已满分区,更稳妥的顺序是:先找出最大的临时文件或日志文件清理出空间 -> 再跑 quotacheck -> quotaon -> setquota。如果你清理空间都无从下手,可以先临时软限制里写入较大的值,等系统腾出空间后再收紧。

6.2 XFS 项目配额在容器场景的用法

现在很多团队在宿主机上用 XFS 给容器数据目录做隔离。比如 Docker 和 Podman 的数据根目录、Kubernetes 的 PV 本地目录,都建议放在独立 XFS 分区上。用项目配额给每个项目目录一个 ID,配合xfs_quota limit -p限制整个项目总占用,比逐个容器设置镜像层大小更直接,也能防止某个容器的日志文件把宿主机系统盘写满。

提一句容易混淆的点:如果你是从 NAS 或者 NFS 挂载过来的目录,配额能不能用,取决于 NFS 服务端的导出选项以及客户端挂载的版本。NFS 本身有quota相关的 RPC 协议,但很多环境根本不生效,最可靠的做法还是在文件所在的服务器本地分区上做配额,而不是在挂载端模拟。

6.3 一句话选型建议

最后总结一下我的选型习惯,方便你直接照抄:

  • 已有 Ext4 分区,要快速限制用户/组空间 -> 用usrquota,grpquota+ quotacheck + edquota,不要为了配额特地去格式化。
  • 新分区,明确有多用户共享目录、目录级限额需求 -> 用 XFS + prjquota,一步到位。
  • 系统盘或根分区 -> 不建议启用配额,除非你很清楚自己在做什么。系统进程和日志写盘最怕被"锁死"。
  • 高可用集群里的共享存储 -> 优先考虑存储端的配额机制,单纯依赖客户端本地文件系统配额经常会因为挂载方式不同而失效。

配额这功能,配置过程本身不难,难的是把软限制、硬限制、宽限期和用户真实使用模型匹配起来。我个人的体会是:第一次做配额宁可设置得宽松一些,观察用户触线频率,再逐步收紧。一上来就把数值压得很低,不仅用户怨声载道,你自己也会被各种"磁盘配额超限"的工单淹没。先给数据,再给规则,配额才能真正成为帮助你管理存储的工具,而不是给自己制造新的麻烦。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询