# 一、概述 diskquota是GPDB用于管理磁盘配额的插件,支持库、表、用户等对象磁盘空间限制。 “软限制”(`diskquota.hard_limit = off`):默认配置。查询开始时检查配额是否超限,所以,DML过程中磁盘使用超限,不会触发报错,仅在下一条SQL有数据写入时参数触发报错。 “硬限制”(`diskquota.hard_limit = on`):DML过程中如果发现磁盘使用超限,终止查询。 但是,硬限制也不是实时的,在配置不当的情况下,“实时性”效果会大打折扣。 # 二、环境 GPDB master分支(相当于GPDB 7) + diskquota插件。 GPDB集群拓扑为3主3备。 # 三、测试用例 ## 3.1 启用diskquota插件 (过程略) ## 3.2 修改diskquota参数 ```bash # 将检查时间间隔调到最大(120秒) gpconfig -c diskquota.naptime -v 120 # 启用硬限制 gpconfig -c diskquota.hard_limit -v on # 重启使参数生效(可以使用gpstop -u,但重启更便于测试) gpstop -a gpstart -a ``` ## 3.3 配额测试 重启后,迅速执行以下SQL: ```sql -- 创建用户 create user user2 with superuser; -- 设置用户配额 select diskquota.set_role_quota('user2', '10 MB'); -- 切换用户 \c - user2 create table t1(a int, b varchar(20)); -- 重启后,120秒内多次插入数据,不会触发超限报错。 insert into t1 select i,10*i from generate_series(1, 4400000) as i; -- 每次插入后,查看使用量统计,发现使用量在120秒内不更新。 select * from diskquota.show_fast_role_quota_view; insert into t1 select i,10*i from generate_series(1, 4400000) as i; ... ``` 在GPDB重启后,120秒内,多次插入数据,每次插入数据量都远大于10MB,但都不会触发磁盘超限报错。直到120秒后,才会触发超限报错。 显然,硬限制的效果与`diskquota.naptime`参数有关,发现超限不是完全由插入操作触发的。 # 四、原因分析 经过对diskquota源代码分析可知: Coordinator上每个database有个名称为“`diskquota bgworker`”的进程,周期性检查各种对象(库、表、用户等)的磁盘使用量是否超限,检查的周期由参数`diskquota.naptime`确定。周期值默认2秒,值越小越能即时发现超限,但CPU消耗越高。进程循环堆栈如下: ``` #0 0x00007fa5d538c143 epoll_wait #1 0x0000000000b74b55 WaitEventSetWaitBlock #2 0x0000000000b74a57 WaitEventSetWait #3 0x0000000000b73ae2 WaitLatch #4 0x00007fa5d712846d disk_quota_worker_main #5 0x0000000000ac104a StartBackgroundWorker #6 0x0000000000accd44 do_start_bgworker #7 0x0000000000acd1cb maybe_start_bgworkers #8 0x0000000000acbe2b process_pm_pmsignal #9 0x0000000000ac7140 ServerLoop #10 0x0000000000ac695b PostmasterMain #11 0x00000000009392e8 main #12 0x00007fa5d52c0f1e __libc_start_main #13 0x00000000004bc779 _start ``` 检查过程中仅标记状态(内部维护一个reject列表,即黑名单),但不会主动触发超限报错。报错的时机由`diskquota.hard_limit`参数确定。 软限制时,在查询开始时,如果发现已标记超限,则报错,查询过程中不报错。 硬限制时,在数据写入过程中(数据落盘新页面申请时),如果发现已标记超限,则报错终止查询。 如果检查周期设置太长,不会及时标记对象磁盘超限状态。因此,无论是软限制还是硬限制都不会“即时”超限报错。 # 五、参考 - [diskquota-archive](https://github.com/greenplum-db/diskquota-archive) - [Greenplum 6新功能介绍之磁盘配额管理工具”Diskquota“](https://segmentfault.com/a/1190000022704426) - [diskquota](https://techdocs.broadcom.com/us/en/vmware-tanzu/data-solutions/tanzu-greenplum/6/greenplum-database/ref_guide-modules-diskquota.html)