背景:Linux Disk Quota是一种限制文件系统资源使用的技术,quota意思是份额、配额的意思,它用来限制用户使用磁盘的额度。可以实现针对用户、群组、目录多维度限制,保证磁盘空间不会因为单一用户或目录导致使用过度,造成磁盘不可用的情况。本文我们来探讨基于XFS文件系统Linux Disk Quota的应用方案。
PS:"360技术”是360团队的线下技术聚合平台,致力于提供有价值的技术干货,点关注哦!
01TIPS
quota的一些使用条件:
Linux内核必须支持quota功能,xfs文件系统本身内置quota
quota在usrquota/grpquota模式下只针对普通用户有效,root老仙法力无边,无法进行限制
关闭SElinux(测试建议关闭)
ext文件系统仅针对整个挂载点限制(<font color=red>即只能基于用户 或 群组进行容量限制,无法针对某一目录进行容量限制</font>)
如果限制目录,尽量不要针对根目录"/"
quota针对整个filesystem进行限制
quota的使用模式:
usrquota:针对用户的设定,仅对普通用户生效,对root无效
grpquota:针对群组的设定
prjquota:针对某个目录的设定,不可与grpquota同时使用(xfs_quota支持)
quota的操作主要流程:
关闭SELinux(测试建议关闭)
编辑/etc/fstab,针对某个文件系统添加quota激活选项
重新挂载指定挂载点
验证quota功能是否生效
使用quota相关命令针对某用户、用户组或某目录设置限制策略
验证磁盘quota策略是否生效
查看磁盘quota使用情况
xfs_quota命令概述:
xfs_quota命令在下面用到很多,简单总结一下常用参数和作用,如下所示:
关于grace time:
grace time的主要作用是当超过quota soft限制用量的情况下,给予一定的宽限时间,当超过grace time,则不可写入,如下图所示。下面案例中会具体用到。
准备:确定Selinux关闭
# sestatus -v
SELinux status: disabled
# 如果是enable状态,临时关闭
setenforce 0
# 持久关闭
vi /etc/selinux/config
SELINUX=disabled
注:如果线上需要开启,可详细查看selinux支持quota的相关参数。
好了,说了那么多,下面开始实战吧~
02:基于用户的配额限制
添加quota激活选项
根据quota限制维度,添加参数usrquota(用户配额),grpquota(组配额)
# vi /etc/fstab
###此处忽略其它配置项,追加如下内容###
##只针对user限制(如果同时需要用户和组限制,添加usrquota,grpquota)
/dev/sdb1 /data xfs defaults,nodiratime,noatime,usrquota 1 2
remount 挂载点
# umount /data
# mount -a
注:xfs文件系统无法通过mount -o remount方式来启动quota功能,必须使用上述方式;
下面检查是否生效:
# mount |grep data
/dev/sdb1 on /data type xfs (rw,noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=32k,usrquota)
注:如果umount时报错:umount: /data: target is busy,就用lsof /data 查看是否有进程在使用,kill掉进程重试。
查看配额是开启
# xfs_quota -x -c "state"
User quota state on /data (/dev/sdb1) #可以看到只有user quota是开启的
Accounting: ON
Enforcement: ON
Inode: #71 (2 blocks, 2 extents)
Group quota state on /data (/dev/sdb1)
Accounting: OFF
Enforcement: OFF
Inode: #67 (1 blocks, 1 extents)
Project quota state on /data (/dev/sdb1)
Accounting: OFF
Enforcement: OFF
Inode: #67 (1 blocks, 1 extents)
Blocks grace time: [7 days]
Inodes grace time: [7 days]
Realtime Blocks grace time: [7 days]
注:如果提示没有xfs_quota命令,则需要 yum -y install xfsprogs安装
对mysql用户进行quota限制
soft配额10M,hard配额20M,grace time 1分钟
##mysql是用户名,配额 soft 10M,hard 20M
# xfs_quota -x -c "limit -u bsoft=10M bhard=20M mysql" /data
##超过Soft配额1分钟后,被限制
# xfs_quota -x -c 'timer -u -b 1minutes' /data
##当超过soft阈值后,Warn/Grace会开始1分钟倒计时
# xfs_quota -x -c "report -ubih" /data
User quota on /data (/dev/sdb1)
Blocks Inodes
User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
---------- --------------------------------- ---------------------------------
root 0 0 0 00 [0 days] 2 0 0 00 [0 days]
mysql 0 10M 20M 00 [------] 0 0 0 00 [------]
测试
场景一:超过hard配额,被限制。
# su - mysql
$ pwd
/data
$ dd if=/dev/zero of=test.dat bs=1M count=30
dd: error writing ‘test.dat’: Disk quota exceeded
21+0 records in
20+0 records out
20971520 bytes (21 MB) copied, 0.0284925 s, 736 MB/s
##Blocks(Used)表示写入了20M数据,超过Blocks(Hard)配额后,直接被限制写入
$ xfs_quota -x -c "report -ubih" /data
User quota on /data (/dev/sdb1)
Blocks Inodes
User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
---------- --------------------------------- ---------------------------------
mysql 20M 10M 20M 00 00:00:41 3 0 0 00 [------]
场景二:超过soft配额,并且超过设置的1分钟grace time,被限制。
# su - mysql
$ pwd
/data
$ dd if=/dev/zero of=test.dat bs=1M count=15
15+0 records in
15+0 records out
15728640 bytes (16 MB) copied, 0.0206793 s, 761 MB/s
##Blocks(Used)表示只写入了15M数据,bsoft<15M<bhard
##超过Blocks(Soft)配额后开始grace time的1分钟倒计时(见Warn/Grace列)
$ xfs_quota -x -c "report -ubih" /data
User quota on /data (/dev/sdb1)
Blocks Inodes
User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
---------- --------------------------------- ---------------------------------
mysql 15M 10M 20M 00 00:00:58 3 0 0 00 [------]
##超过Blocks(Soft)配额1分钟后
$ xfs_quota -x -c "report -ubih" /data
User quota on /data (/dev/sdb1)
Blocks Inodes
User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
---------- --------------------------------- ---------------------------------
mysql 15M 10M 20M 00 [0 days] 3 0 0 00 [------]
##再次写入失败
$ dd if=/dev/zero of=test02.dat bs=1M count=1
dd: failed to open ‘test02.dat’: Disk quota exceeded
注:上述只是限制mysql用户在/data 挂载点的使用
说明:
bsoft是软限制,磁盘空间超过bsoft,但小于bhard,此时将进入“宽限期”(grace time)倒计时,如果在宽限期间内将容量降低到bsoft以下,则grace time消失,否则拒绝继续写入
bhard是硬限制,超过此限制值,将无法再继续写入
其它目录测试
在其他挂载点是不限制的,例如/home/mysql下:
# su - mysql
$ cd /home/mysql
$ dd if=/dev/zero of=test.dat bs=1M count=50
50+0 records in
50+0 records out
52428800 bytes (52 MB) copied, 0.0190618 s, 2.8 GB/s
$ ll
total 51200
-rw-r--r-- 1 mysql mysql 52428800 Jul 5 02:17 test.dat
$ pwd
/home/mysql
至此,基于用户的quota方案,部署就完成了。
03基于目录的配额限制
添加quota激活选项
修改/etc/fstab,添加 prjquota(即单一目录配额模式)
# vi /etc/fstab
/dev/sdb1 /data xfs defaults,nodiratime,noatime,prjquota 1 2
remount 挂载点
# umount /data
# mount -a
注:xfs文件系统无法通过mount -o remount方式来启动quota功能,必须使用上述方式。
下面检查是否生效:
# mount | grep data
/dev/sdb1 on /data type xfs (rw,noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=32k,prjquota)
注:如果umount时报错:umount: /data: target is busy,就用lsof /data 查看是否有进程在使用,如进程无用,kill掉进程重试。
查看配额是否开启
通过如下命令也可以查看到quota基于project的配额限制功能是开启状态
# xfs_quota -x -c 'state'
User quota state on /data (/dev/sdb1)
Accounting: OFF
Enforcement: OFF
Inode: #71 (2 blocks, 2 extents)
Group quota state on /data (/dev/sdb1)
Accounting: OFF
Enforcement: OFF
Inode: #67 (1 blocks, 1 extents)
Project quota state on /data (/dev/sdb1) ##可以看到只有project quota是开启的
Accounting: ON
Enforcement: ON
Inode: #67 (1 blocks, 1 extents)
Blocks grace time: [7 days]
Inodes grace time: [7 days]
Realtime Blocks grace time: [7 days
注:如果提示没有xfs_quota命令,则需要 yum -y install xfsprogs安装
创建目录和项目名对应关系
创建项目标识语句如下:
##创建项目id与目录的对应关系
# echo "1:/data/mysqldata" >> /etc/projects
##创建项目id与项目名称的对应关系,即给项目id起个别名
# echo "mysqldata:1" >> /etc/projid
初始化项目语句如下:
# xfs_quota -x -c "project -s mysqldata"
Setting up project mysqldata (path /data/mysqldata)...
Processed 1 (/etc/projects and cmdline) paths for project mysqldata with recursion depth infinite (-1).
Setting up project mysqldata (path /data/mysqldata)...
Processed 1 (/etc/projects and cmdline) paths for project mysqldata with recursion depth infinite (-1).
Setting up project mysqldata (path /data/mysqldata)...
Processed 1 (/etc/projects and cmdline) paths for project mysqldata with recursion depth infinite (-1).
注:会显示上述一堆这样的信息,不要害怕,是OK的,一切尽在掌握之中
此时可以查看到目录是否存在对应项目:
# xfs_quota -x -c "print" /data
Filesystem Pathname
/data /dev/sdb1 (pquota)
/data/mysqldata /dev/sdb1 (project 1, mysqldata)
设置目录quota大小
##针对项目mysqldata设置10M容量硬限制
# xfs_quota -x -c "limit -p bsoft=6M bhard=10M mysqldata" /data
##查看是否生效,以及使用情况
# xfs_quota -x -c "report -bih" /data
Project quota on /data (/dev/sdb1)
Blocks Inodes
Project ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace
---------- --------------------------------- ---------------------------------
#0 20M 0 0 00 [------] 4 0 0 00 [------]
mysqldata 0 6M 10M 00 [------] 1 0 0 00 [------]
说明:
bsoft是软限制,磁盘空间超过bsoft,但小于bhard,此时将进入“宽限期”(grace time)倒计时,如果在宽限期间内将容量降低到bsoft以下,则grace time消失,否则拒绝继续写入;
bhard是硬限制,超过此限制值,将无法再继续写入;
测试
此时在目录/data/mysqldata/下写入15M文件,则报错,并且只写入了10M内容
# dd if=/dev/zero of=/data/mysqldata/test.dat bs=1M count=15
dd: error writing ‘/data/mysqldata/test.dat’: No space left on device
11+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.296038 s, 35.4 MB/s
# du -sh /data/mysqldata/*
10M /data/mysqldata/test.dat
此时可以通过如下命令查看使用情况:
# xfs_quota -x -c "df -h" /data/
Filesystem Size Used Avail Use% Pathname
/dev/sdb1 6.0G 62.2M 5.9G 1% /data
/dev/sdb1 6M 10M 8192.0E 167% /data/mysqldata
如果想要另外添加新的限制目录,就根据上面步骤进行即可;
至此,基于单一目录的quota方案,部署就完成了。
04常用运维命令
暂时关闭quota限制功能
# xfs_quota -x -c "disable -up" /data
# xfs_quota -x -c "state" /data
User quota state on /data (/dev/sdb1)
Accounting: OFF
Enforcement: OFF
Inode: #71 (2 blocks, 2 extents)
Group quota state on /data (/dev/sdb1)
Accounting: OFF
Enforcement: OFF
Inode: #67 (1 blocks, 1 extents)
Project quota state on /data (/dev/sdb1)
Accounting: ON
Enforcement: OFF ##可以看到OFF状态了
Inode: #67 (1 blocks, 1 extents)
Blocks grace time: [7 days]
Inodes grace time: [7 days]
Realtime Blocks grace time: [7 days
重新开启quota功能
xfs_quota -x -c "enable -p" /data
彻底关闭quota功能
xfs_quota -x -c "off -up" /data
注:之后就不能再通过enable方式启动了,必须执行:umount /data;mount -a 重新激活quota功能
调大容量限制
直接重新执行一遍设置就好:
##针对用户
xfs_quota -x -c "limit -u bsoft=100M bhard=200M mysql" /data
##针对目录
xfs_quota -x -c "limit -p bsoft=60M bhard=100M mysqldata" /data
重建目录会影响quota限制吗?
重建目录会影响quota限制,无论是如下哪种方式新建的相同名字目录都会失去quota的限制:
mv /data/mysqldata /data/mysqldata_bak
mkdir /data/mysqldata
或者:
rm -rm /data/mysqldata
mkdir /data/mysqldata
解决方法:
使用如下方式重新初始化这个项目:
xfs_quota -x -c "project -s mysqldata"
注:仅仅这样初始化一下就好,无需再去重新设定限制
如何调整“宽限期”(grace time)
宽限期,分为user、group、project维度,通过timer -u -g -p修改
##针对user,用户的grace time时间
xfs_quota -x -c "timer -u -b 14days" /data
##针对group,用户组的grace time时间
xfs_quota -x -c "timer -g -b 14days" /data
##针对project,单一目录的grace time时间
xfs_quota -x -c "timer -p -b 14days" /data
05总结
本文写作本着实用至上的原则,让读者可以快速部署磁盘配额。主要介绍针对XFS文件系统的Quota方案,并且只是基于blocks的容量限制,不涉及其它文件系统,以及文件数量配额限制。
参考:
RedHat :
https://access.redhat.com/documentation/en-
us/red_hat_enterprise_linux/6/html/storage_administration_guide/ch-disk-quotas
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/storage_administration_guide/xfsquota
Linux manual page:https://man7.org/linux/man-pages/man8/xfs_quota.8.html
《鸟哥私房菜》:
http://linux.vbird.org/linux_basic/0420quota.php#quota_flow