跳转至

资源管理

资源管理概述

资源管理也叫资源限制,是控制数据库对CPU、并发数和内存等系统资源的使用,它有几个核心功能:

  • 一方面限制整个数据库所占用的资源。

  • 另一方面控制数据库内不同任务,不同角色之间的资源分配。

对于数据库内不同任务的资源分配,Seabox数据库建立了“资源组”的概念,各个资源组之间有不同的资源配额。

需要说明的是,“资源管理”从广义角度来说,所有与资源限制相关的方法与机制均可称为“资源管理”。但是,本文除特别说明外,专指基于“资源组”的狭义概念“资源管理”,即“资源组管理”。

安装资源管理组件

Seabox数据库支持cgroup(第一版,下文称作“cgroup v1”)以及cgroup v2,需要选择满足要求的Linux操作系统版本。

注意:不同的Linux发行版默认的cgroup版本不尽相同,而且存在cgroup v1和v2混合模式的情况,Seabox数据库目前不支持cgroup v1和v2混合模式,即,cgroup v1和v2只能二选一配置。

以下分成两个小结分别介绍cgroup v1和v2的配置方法。

install_resmgr.sh兼容性

本章节将会使用install_resmgr.sh脚本初始化cgroup配置,因为软件版本的升级,配置脚本存在兼容性问题。请记住以下原则:

如果在同一个系统环境下,安装了多个版本的Seabox数据库,那么请始终仅使用最新版本的install_resmgr.sh脚本。

cgroup v1

如果使用cgroup v2,则可以忽略本小结内容。

v1:先决条件

使用cgroup v1,则操作系统需要满足:

  • 在RedHat 6.x 和 CentOS 6.x系统下,当启用资源组资源管理时,会引起Seabox数据库性能大幅退化。这是由此版操作系统的Linux内核cgroup v1 bug导致的,CentOS 7.x 和 Red Hat 7.x系统已经修复了该问题。
  • 如果在RedHat 6系统中使用Seabox数据库的资源组功能,你需要将系统内核升级到2.6.32-696或更高版本。
  • 为了获得更稳定的cgroup功能,Seabox要求Linux内核最小版本为2.7。
v1:配置操作系统cgroup

如果Seabox数据库已经安装,可以使用本方式配置。此操作仅需要执行一次。

在Seabox数据库所有节点上使用Linux的root权限运行install_resmgr.sh,脚本会自动识别cgroup版本。

注意:集群扩容操作后,需要在新扩容的节点上也执行本操作。

# username 是运行SeaboxMPP/SeaboxSQL的Linux用户名
# 本文假设username为seabox
install_resmgr.sh username

安装完成后,需要重启Seabox数据库。

请注意脚本执行输出信息:

[root@test-4 ~]# install_resmgr.sh seabox
...
INFO: cgroup v1 mount on /sys/fs/cgroup
INFO: init top group for users on subsystems ...
INFO:     username: cpu, cpuset, memory, blkio, net_cls ('x' means the subsystem is disabled)
INFO:       seabox:  OK,     OK,     OK,     x,      OK
NOTICE: some subsystems are disabled
...

如果某个子系统标注为“x”表示该子系统不可用。

Seabox数据库要求:cpu子系统是必不可少的,如果不可用,则Seabox数据库将无法启动。其它子系统都是可选的,如果不可用,Seabox内部将自动屏蔽该子系统。

v1:验证操作系统cgroup

cgroup v1将不同资源的控制单元称为“子系统(sub system)”。

验证操作系统cgroup配置是否正确。

(1)识别cgroup目录挂载点:

$ grep -w cgroup /proc/mounts
或者:
$ grep -w cgroup /proc/self/mounts

以上命令结果的第一行就是挂载点。以下假设挂载点为:/sys/fs/cgroup/

(2)验证配置:

查看以上步骤确立的各子系统顶层路径下是否已经创建了scdb_seabox文件夹。

ls -l /sys/fs/cgroup/cpu/scdb_seabox
ls -l /sys/fs/cgroup/cpuacct/scdb_seabox
ls -l /sys/fs/cgroup/cpuset/scdb_seabox
ls -l /sys/fs/cgroup/memory/scdb_seabox
ls -l /sys/fs/cgroup/blkio/scdb_seabox

如果以上目录都存在,且所有者是seabox,说明配置正确。

注意:cpu是Seabox必须的子系统,如果缺失将导致Seabox资源组管理不可用,Seabox数据库无法启动。其它子系统均为可选的,如果缺失只会导致对应的资源限制功能失效,不会导致Seabox数据库无法使用。

v1:blkio子系统特殊性

部分Linux发行版本没有配置blkio子系统。需要确认Linux内核配置满足以下要求:

CONFIG_BLK_CGROUP=y
CONFIG_BLK_DEV_THROTTLING=y

通常,Linux内核配置在/boot/config-XXX文件,例如:/boot/config-3.10.0-957.el7.x86_64。

如果Linux内核配置不满足上述条件,需要变更配置后重新编译内核或者更换内核。

注意:

  1. blkio子系统是Seabox数据库的可选功能,缺失不影响io_speed功能。
  2. 因为部分Linux系统存在缺陷,Seabox数据库允许强制禁止使用blkio子系统,详见sc_resgroup_enable_blkio参数说明。

cgroup v2

如果使用cgroup v1,则可以忽略本小结内容。

v2:先决条件

使用cgroup v2,则操作系统需要满足:

  • 要求Linux最小内核版本为4.15。5.0以下版本不支持cpuset控制器,推荐使用5.2或更高版本。
  • 要求Linux最小systemd版本为239,可以使用systemctl --version命令查询systemd版本号。
v2:切换到cgroup v2

不同Linux发行版启用cgroup v2的方法有差异。

RedHat/CentOS 8.5切换方法:

[root@test ~]# vim /etc/default/grub
GRUB_CMDLINE_LINUX添加配置项:"cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1"

[root@test ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
[root@test ~]# reboot

Ubuntu 21切换方法:

[root@test ~]# vim /etc/default/grub
GRUB_CMDLINE_LINUX添加配置项:"cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1"

[root@test ~]# update-grub
[root@test ~]# reboot
v2:配置操作系统cgroup

如果Seabox数据库已经安装,可以使用本方式配置。此操作仅需要执行一次。

在Seabox数据库所有节点上使用Linux的root权限运行install_resmgr.sh,脚本会自动识别cgroup版本。

注意:集群扩容操作后,需要在新扩容的节点上也执行本操作。

# username 是运行SeaboxMPP/SeaboxSQL的Linux用户名
# 本文假设username为seabox
install_resmgr.sh -u username

install_resmgr.sh详细参数说明请使用“-h”参数查询。

参数:

  • -u:用户名
  • -d:cgroup层级顶层目录名,如果以“/”开头,则表示完整目录名,与sc_resource_group_cgroup_parent参数对应,否则为目录名前缀。
  • -t:Seabox数据库工作在多线程模式(MT)。由于cgroup v2的限制,一旦cgroup组切换到线程模式(threaded),将无法再切回进程模式(domain),因此,Seabox从线程模式切换到进程模式需要重新执行install_resmgr.sh脚本。
  • -h:显示帮助信息。

安装完成后,需要重启Seabox数据库。

请注意脚本执行输出信息:

[root@test-4 ~]# install_resmgr.sh -u seabox
...
INFO: cgroup v2 mount on /sys/fs/cgroup
INFO: init root cgroup's cgroup.subtree_control ...
INFO: cpu, cpuset, memory, pids, io ('x' means the controller is disabled)
INFO:  OK,     OK,     OK,   OK,  x
NOTICE: some controllers are disabled
...

如果某个控制器被标注为“x”表示该控制器不可用。

Seabox数据库要求:cpu控制器是必不可少的,如果不可用,则Seabox数据库将无法启动。其它控制器都是可选的,如果不可用,Seabox内部将自动屏蔽该控制器。

v2:验证操作系统cgroup

cgroup v2将不同资源的控制单元称为“控制器(controller)”。

验证操作系统cgroup配置是否正确。

(1)识别cgroup目录挂载点:

$ grep -w cgroup2 /proc/mounts
或者:
$ grep -w cgroup2 /proc/self/mounts

以上命令结果的第一行就是挂载点。以下假设挂载点为:/sys/fs/cgroup/

(2)验证配置:

查看以上步骤确立的各子系统顶层路径下:

  • 是否已经创建了scdb_seabox文件夹;
  • 检查scdb_seabox文件夹的cgroup.controllers的控制器。
  • 检查scdb_seabox文件夹的cgroup.subtree_control的控制器。
$ ls -l /sys/fs/cgroup/scdb_seabox/
-rw-r--r-- 1 seabox seabox 0 Apr  8 14:13 cpu.max
-r--r--r-- 1 seabox seabox 0 Apr  8 14:13 cpu.stat
-rw-r--r-- 1 seabox seabox 0 Apr  8 14:13 cpu.weight
-rw-r--r-- 1 seabox seabox 0 Apr  8 14:13 cpu.weight.nice
...

$ cat /sys/fs/cgroup/scdb_seabox/cgroup.controllers 
cpu cpuset io memory pids rdma

$ cat /sys/fs/cgroup/scdb_seabox/cgroup.subtree_control
cpu cpuset io

注意:

  • cpu是Seabox必需的控制器,如果缺失将导致Seabox资源组管理不可用,Seabox数据库无法启动。其它控制器均为可选的,如果缺失只会导致对应的资源限制功能失效,不会导致Seabox数据库无法使用。
  • 与cgroup v1不同,cgroup v2没有与net_cls子系统相对应的控制器。
v2:io控制器的特殊性

部分Linux发行版本没有配置io控制器。需要确认Linux内核配置满足以下要求:

CONFIG_BLK_CGROUP=y
CONFIG_BLK_DEV_THROTTLING=y

通常,Linux内核配置在/boot/config-XXX文件,例如:/boot/config-6.5.0-18-generic。

如果Linux内核配置不满足上述条件,需要变更配置后重新编译内核或者更换内核。

注意:

  1. io控制器是Seabox数据库的可选功能,缺失不影响io_speed功能。
  2. Seabox数据库允许强制禁止使用io控制器,详见sc_resgroup_enable_blkio参数说明。

支持的资源类型

Seabox数据库包含VE引擎和PG引擎,他们支持的资源管理功能如下:

资源类型 PG引擎 VE引擎
并发任务数 支持 支持
CPU使用绝对比例(资源组绝对使用率) 支持 支持
CPU使用相对比例(资源组竞争使用率) 支持 支持
CPU指定核数 支持 支持
内存限制 支持 支持
IO速率 支持 支持
队列优先级 支持 支持

需要注意的是:

  • 资源管理方式支持group和none两种方式:

  • none:不使用资源管理,资源使用近乎无限制(仅有简单约束)。默认配置。

  • group:资源组管理方式。

  • PG引擎与VE引擎应用场景不同,资源管理方式也有所差异:

  • VE引擎内存资源管理还有一套专用的配置参数。

  • CPU使用率和CPU指定核数只能设置为其中的一种。

启停资源管理

配置参数

资源管理方式支持group、group-v2和none三种方式,通过参数控制:

  • 关闭资源管理(默认)
seabox config -c sc_resource_manager -v 'none'
  • 打开资源管理
# 使用cgroup v1:
seabox config -c sc_resource_manager -v 'group'

# 使用cgroup v2:
seabox config -c sc_resource_manager -v 'group-v2'

修改配置后,需要重启Seabox数据库才能生效。

当资源管理方式配置为group或group-v2时,可以通过参数sc_resource_group_activate来临时激活或禁止资源组管理,且不需要重启数据库。详见sc_resource_group_activate参数说明。

检查资源管理是否生效

Seabox数据库启动后,通过检查Seabox数据库的各实例的sd_log日志,以确认资源管理是否已经生效,如果日志有以下类似内容,表明该实例的资源组功能已生效(注:不同版本的log有差异)。

如果配置为cgroup v1,则:

2022-07-13 11:54:49.927 CST [34986] LOG:  scdb dir for valid cgroup component "cpu": /sys/fs/cgroup/cpu/scdb_seabox/
2022-07-13 11:54:49.927 CST [34986] LOG:  scdb dir for valid cgroup component "cpuacct": /sys/fs/cgroup/cpuacct/scdb_seabox/
2022-07-13 11:54:49.927 CST [34986] LOG:  scdb dir for valid cgroup component "memory": /sys/fs/cgroup/memory/scdb_seabox/
2022-07-13 11:54:49.927 CST [34986] LOG:  scdb dir for valid cgroup component "cpuset": /sys/fs/cgroup/cpuset/scdb_seabox/
2022-07-13 11:54:49.927 CST [34986] LOG:  scdb dir for valid cgroup component "blkio": /sys/fs/cgroup/blkio/scdb_seabox/

如果日志出现类似以下错误,表明该实例的资源组配置有问题,建议按照“安装资源管理组件”章节的内容检查操作系统的cgroup是否正确配置。

2023-03-29 13:24:06.743 CST [24587] FATAL:  cgroup is not properly configured: can't access directory "/sys/fs/cgroup/cpu/scdb_seabox/"

如果配置为cgroup v2,则:

2024-04-08 14:14:38.061 CST [35133] 0.0.0 LOG:  scgb dir for cgroup v2: /sys/fs/cgroup/scdb_seabox/
2024-04-08 14:14:38.061 CST [35133] 0.0.0 LOG:  cgroup v2 controller "cpu" is valid
2024-04-08 14:14:38.061 CST [35133] 0.0.0 LOG:  cgroup v2 controller "cpuset" is valid
2024-04-08 14:14:38.061 CST [35133] 0.0.0 LOG:  cgroup v2 controller "io" is valid
2024-04-08 14:14:38.061 CST [35133] 0.0.0 LOG:  cgroup v2 controller "net_cls" is invalid

如果日志出现有关cgroup的ERROR或者FATAL错误,表明该实例的资源组配置有问题。

资源组操作

资源组就是一些关于并发度、CPU、内存和IO等资源限制的规则组,不同类型的任务使用不同的资源组,来实现资源的合理调配。

在这一章里,重点介绍资源组的创建,删除和查看等操作。对资源的详细管理,将在后面的章节详细介绍。

缺省资源组

Seabox数据库安装并初始化后,已经创建了三个缺省的资源组:admin_group、default_group和system_group。当启用资源组后,任何没有明确指定资源组的角色都会被指定一个缺省的资源组。

  • SUPERUSER角色指定admin_group。
  • 非管理员角色指定default_group。
  • Seaboxmaster以及辅助进程不属于任何角色,因此由system_group组来控制。

admin_group、default_group和system_group区别如下:

限制类型 admin_group default_group system_group
CONCURRENCY 10 20 0
CPU_RATE_LIMIT 10 20 10
CPU_RATE_CEILING -1 -1 -1
CPUSET -1 -1 -1
MEMORY_LIMIT -1 -1 -1
IO_KBPS 0 0 0
IC_KBPS 0 0 0
QUEUE_PRIORITY -1 -1 -1

system_group比较特殊,“checkpointer”、“walwriter”等这类进程属于辅助进程,不属于特定的角色,因此统一由system_group来控制。system_group目前仅支持CPU_RATE_LIMIT、CPU_RATE_CEILING和CPUSET几种类型属性,其它属性无效。

创建资源组

当为角色创建资源组时,需要通过一个名字和CPU资源分配模式。可选项包括:事务并发度限制、内存限制等。使用 CREATE RESOURCE GROUP 命令创建新的资源组。

可以指定MEMORY_LIMIT值为这个资源组设置内存使用量限制。如果MEMORY_LIMIT=-1,则该资源组的内存使用量无限制。

语法
CREATE RESOURCE GROUP name WITH (group_attribute=value [, ... ])

group_attribute 可以是:

CPU_RATE_LIMIT=整数 | CPU_RATE_CEILING=整数 | CPUSET=tuple
[ CONCURRENCY=整数 ]
[ MEMORY_LIMIT=整数 ]
[ IO_KBPS=整数 ]
[ IC_KBPS=整数 ]
[ QUEUE_PRIORITY=整数 ]

  • IO_KBPS
描述: 限制IO每秒读写字节数,单位为KB/s。
类型: 整形
范围: [0-最大32位整数], 0代表不限速。
默认: 0
  • IC_KBPS
描述: 限制内部数据传输每秒字节数,单位为KB/s。
类型: 整形
范围: [0-最大32位整数], 0代表不限速。
默认: 0
  • QUEUE_PRIORITY
描述: 队列优先级。
类型: 整形
范围: [-1, 0, 1, 2], -1表示无优先级(即不受队列优先级控制),0、1和2分别表示低、中和高优先级。
默认: -1
示例

例如,创建一个名为rgroup1的资源组,CPU相对使用率限制为20%,内存限制500MB,则:

=# CREATE RESOURCE GROUP rgroup1 WITH (CPU_RATE_LIMIT=20, MEMORY_LIMIT=500);

CPU相对使用率20%,被rgroup1资源组的所有角色共享。类似地,内存限制500MB,被rgroup1资源组的所有角色共享。CONCURRENCY缺省值20。

删除资源组

被删除的资源组不能被指派给任何角色,也不能被任何活动的或者等待的事务关联。

缺省资源组无法被删除,只能被修改。

语法
DROP RESOURCE GROUP group_name
约束条件
  • 只有超级用户可以删除资源组。
  • 删除资源组后,其所拥有的CPU,内存等资源将归还系统。
  • 要删除的资源组不能正在被任何角色或查询语句使用。
  • 不能删除缺省资源组。
  • 不能在显式事务或子事务中删除资源组。
参数说明
  • group_name
描述: 资源组名称
类型: 字符串

修改资源组

ALTER RESOURCE GROUP 命令可以更新资源组设定值,例如:

ALTER RESOURCE GROUP rg_role_light SET CONCURRENCY 7;

注:不能将admin_group资源组的CONCURRENCY值设置为0。

资源组与角色映射

一个资源组可以被指派给一个或多个角色。

可以在创建角色同时指定资源组

CREATE RESOURCE GROUP r1 WITH (CPU_RATE_LIMIT=5, MEMORY_LIMIT=500);
CREATE ROLE r1 WITH LOGIN RESOURCE GROUP g1; -- 指定角色r1到资源组g1上

创建角色时若不指定资源组,则超级用户角色缺省指派admin_group资源组,其他角色缺省指派default_group资源组。

CREATE RESOURCE GROUP r1 WITH (CPU_RATE_LIMIT=5, MEMORY_LIMIT=500);
CREATE ROLE r1 WITH LOGIN;            -- 关联default group
CREATE ROLE r2 WITH SUPERUSER LOGIN;  -- 关联admin group

可以将已有的角色与资源组关联

ALTER ROLE r1 RESOURCE GROUP g1;  -- 将角色r1关联到资源组g1上
  • 解除角色与资源组的关联
ALTER ROLE r1 RESOURCE GROUP none;

监视资源组状态

Seabox数据库内置了一系列sc_toolkit视图,来查看当前资源组的状况。

查看资源组配置

SELECT * FROM sc_toolkit.sc_resgroup_config;
 groupid |   groupname   | manage_group | parentgroupid | concurrency | cpu_rate_limit | cpu_rate_ceiling | cpuset | memory_limit | io_kbps | ic_kbps | queue_priority 
---------+---------------+--------------+---------------+-------------+----------------+------------------+--------+--------------+---------+---------+----------------
    6437 | default_group |            0 |             0 | 20          | 20             | -1               | -1     | -1           | 0       | 0       | -1
    6438 | admin_group   |            0 |             0 | 10          | 10             | -1               | -1     | -1           | 0       | 0       | -1
    6441 | system_group  |            0 |             0 | 0           | 10             | -1               | -1     | -1           | 0       | 0       | -1
   16384 | rg_test       |            0 |             0 | 20          | 20             | -1               | -1     | -1           | 0       | 0       | -1
(4 rows)

查看资源组资源使用情况

sc_toolkit.sc_resgroup_status:

\x
SELECT * FROM sc_toolkit.sc_resgroup_status WHERE rsgname='default_group';

该视图显示default_group资源组运行中的和正在排队的事务个数,也可以显示资源组的CPU和内存使用率。

-[ RECORD 1 ]--------
rsgname              | default_group
groupid              | 6437
num_running          | 0
num_queueing         | 0
num_queued           | 0
num_executed         | 0
total_queue_duration | 00:00:00
cpu_usage            | {"-1":0.00, "0":0.00, "1":0.00, "2":0.00}
memory_usage         | {"-1":0, "0":0, "1":0, "2":0, "-2":0}
io_speed             | {"-1":0.00, "0":0.00, "1":0.00, "2":0.00, "-2":0.00}
ic_speed             | {"-1":0.00, "0":0.00, "1":0.00, "2":0.00, "-2":0.00}

(1 row)

sc_toolkit.sc_resgroup_summary:

sc_toolkit.sc_resgroup_status有诸多相似之处,但本视图效率更高,sc_toolkit.sc_resgroup_status因为需要计算速率,所以至少需要300ms。

本视图仅统计事务数,效率更高。另外,sc_toolkit.sc_resgroup_statusnum_running字段统计全部正在执行的事务数,包括bypass的。而本视图的num_running字段是不包含bypass事务的。

seaboxsql=# select * from sc_toolkit.sc_resgroup_summary;
-[ RECORD 1 ]--------+--------------
rsgname              | default_group
groupid              | 6437
concurrency          | 20
global_concurrency   | -1
actual_concurrency   | 20
num_running          | 0
num_queueing         | 0
num_queued           | 0
num_executed         | 0
total_queue_duration | 00:00:00

显示每个host的资源组CPU/内存使用率

Seabox数据库可以部署在1个或多个host(服务器)上,以1个Coordinator节点(即Master节点),3个执行节点为例,可以部署成

image

还可以部署成

image

SELECT * FROM sc_toolkit.sc_resgroup_status_per_host;

按部署方案1的示例输出,memory_used 等内存单位是MB

    rsgname     | groupid | hostname | cpu  | memory_used | io_speed | ic_speed 
----------------+---------+----------+------+-------------+----------+----------
 rg_bypass_test |   16384 | test-4   | 0.00 |           0 | 0.00     | 0.00     
 admin_group    |    6438 | test-4   | 0.01 |           1 | 0.00     | 0.00     
 default_group  |    6437 | test-4   | 0.00 |           0 | 0.00     | 0.00     
(3 rows)

显示每个executor的资源组CPU/内存使用率

SELECT * FROM sc_toolkit.sc_resgroup_status_per_executor;

executor_id -1 代表Coordinator节点, 0-2代表3个执行节点

示例输出

    rsgname     | groupid | hostname | executor_id | cpu  | memory_used | io_speed | ic_speed 
----------------+---------+----------+-------------+------+-------------+----------+----------
 admin_group    |    6438 | test-4   |           0 | 0.00 |           0 | 0.00     | 0.00     
 default_group  |    6437 | test-4   |           1 | 0.00 |           0 | 0.00     | 0.00     
 rg_bypass_test |   16384 | test-4   |           0 | 0.00 |           0 | 0.00     | 0.00     
 rg_bypass_test |   16384 | test-4   |           2 | 0.00 |           0 | 0.00     | 0.00     
 admin_group    |    6438 | test-4   |           2 | 0.00 |           0 | 0.00     | 0.00     
 default_group  |    6437 | test-4   |          -1 | 0.00 |           0 | 0.00     | 0.00     
 admin_group    |    6438 | test-4   |           1 | 0.01 |           0 | 0.00     | 0.00     
 default_group  |    6437 | test-4   |           0 | 0.00 |           0 | 0.00     | 0.00     
 rg_bypass_test |   16384 | test-4   |          -1 | 0.00 |           0 | 0.00     | 0.00     
 rg_bypass_test |   16384 | test-4   |           1 | 0.00 |           0 | 0.00     | 0.00     
 admin_group    |    6438 | test-4   |          -1 | 0.04 |           1 | 0.00     | 0.00     
 default_group  |    6437 | test-4   |           2 | 0.00 |           0 | 0.00     | 0.00     
(12 rows)

查看资源组指派的角色

执行以下查询,查看分派给角色的资源组:

SELECT rolname, rsgname FROM pg_roles, pg_resgroup WHERE pg_roles.rolresgroup=pg_resgroup.oid;
-- 部分版本提供以下视图:
SELECT * FROM sc_toolkit.sc_resgroup_role;

示例输出

         rrrolname         |  rrrsgname
---------------------------+----------------
 seabox                    | admin_group
 pg_monitor                | admin_group
 pg_read_all_settings      | admin_group
 pg_read_all_stats         | admin_group
 pg_stat_scan_tables       | admin_group
 pg_read_server_files      | admin_group
 pg_write_server_files     | admin_group
 pg_execute_server_program | admin_group
 pg_signal_backend         | admin_group
 sd_dba                    | admin_group
 sd_sso                    | admin_group
 sd_sao_owner              | admin_group
 sd_sao_etl                | admin_group
 sd_sao                    | admin_group
 role_bypass_test          | rg_bypass_test
 r1                        | default_group
(16 rows)

取消资源组内正在执行或者排队的事务

例如,执行以下查询语句,先查看所有资源组当前全部活动或者等待的语句。如果查询返回空集,则没有任何资源组相关的事务正在执行或者排队。

SELECT
    rolname, g.rsgname, pid, state, query
FROM
    pg_roles, sc_toolkit.sc_resgroup_status g, pg_stat_activity
WHERE
    pg_roles.rolresgroup=g.groupid
    AND pg_stat_activity.usename=pg_roles.rolname;

执行结果样例:

rolname | rsgname | pid | state | query
---------+----------+---------+---------+--------+-------------
sammy | rg_light | 31861 | idle | SELECT * FROM mytesttbl;
billy | rg_light | 31905 | active | SELECT * FROM topten;

这个查询结果中有pid,假设要取消pid为31905的处理进程,可以这样:

SELECT pg_cancel_backend(31905);

注:请勿使用KILL命令终止Seabox数据库进程。

查询迁移到其它资源组

超级用户可以使用sc_toolkit.pg_resgroup_move_query(pid,'资源组名')函数将一个正在运行的查询(无需停止该查询)从一个资源组迁移到另一个资源组。这样可以将一个长查询迁移到一个资源充足的资源组继续执行。

例如,将31905进程迁移至 default_group 资源组:

SELECT sc_toolkit.pg_resgroup_move_query(31905, 'default_group') FROM pg_stat_activity WHERE wait_event_type='ResourceGroup';

注:可以迁移一个活动的或者正在执行的查询,但是不能迁移一个排队或者挂起中的查询。

并发管理

资源组CONCURRENCY属性,用来控制角色资源组允许的最大并发事务数。

角色的每个资源组逻辑上划分出与CONCURRENCY限制属性一样的固定数量的插槽(slot)。Seabox数据库给这些插槽分配相等的固定的内存值。CONCURRENCY限制属性默认值是20。

当资源组的并发事务达到CONCURRENCY上限后,新提交的事务都将进入排队。此时,当一个运行中的事务完成且内存资源充足的情况下,Seabox数据库将队列中最早的事务开始执行。

可设置数据库的配置参数sc_resource_group_bypass来绕过资源组并发限制。

各个资源组的连接数之和不能超过max_connections。

例如:

max_connections范围[1,261243] 默认100,可以通过修改配置文件修改

当达到资源组设置的连接上限max_connections时,查询将被挂起, 但有2种情况例外

  • set 命令不受限。
  • 参数 sc_resource_group_bypass = on 时,该参数默认off。

CPU管理

Seabox数据库的CPU使用率

参数sc_resource_group_cpu_limit限制了每个Seabox数据库在相应主机上可以分配到的CPU资源最大百分比。该限制参数统一限定了主机上所有资源组的最大CPU使用率。剩余的未分配CPU资源被操作系统内核及其他进程(含Seabox数据库的mirror进程)使用。

范围是[0.1-1.0] 代表10%~100%, 默认0.9。

  • 数据库运行不一定能达到sc_resource_group_cpu_limit设定的值,因为其他非进程可能会抢占资源
  • 避免将该参数设置超过0.9。超过0.9时可能会在高负载情况下造成使用全部CPU资源,导致数据库辅助管理进程无法争抢到CPU资源。

sc_resource_group_cpu_limit限制了总配额,而各个资源组内的CPU_RATE_LIMIT只有在所有资源组都达到总配额的情况才生效。下面通过几个例子来说明:

假设sc_resource_group_cpu_limit设为0.9,有4个资源组:

资源组 CPU_RATE_LIMIT
admin_group 10
default_group 20
system_group 10
user_group 60

例1: 当非数据库进程空闲,admin_group、default_group和system_group也空闲时,user_group最大可使用为90%。

资源组 CPU_RATE_LIMIT 实际使用的CPU
admin_group 10 0%
default_group 20 0%
system_group 10 0%
user_group 60 0-90%

例2: 当非数据库进程占比50%,admin_group、default_group和system_group也空闲时,user_group最大可使用为50%

资源组 CPU_RATE_LIMIT 实际使用的CPU
admin_group 10 0%
default_group 20 0%
system_group 10 0%
user_group 60 0-50%

例3: 非数据库进程占比50%,四个资源组都需要100%的CPU,发生争抢。此时数据库实际可用CPU只有50%, 当数据库所有资源组需求超过50%就会发生争抢。

资源组 CPU_RATE_LIMIT 实际使用的CPU
admin_group 10 5%
default_group 20 10%
system_group 10 5%
user_group 60 30%

警告:

  • 默认值可能不够Seabox数据库运行多个负载,因此需要合理调整参数。
  • 避免将该参数设置超过0.9。超过0.9时可能会在高负载情况下造成使用全部CPU资源,导致数据库辅助管理进程无法争抢到CPU资源。

角色的CPU资源限制

相对(共享)百分比

使用CPU_RATE_LIMIT属性配置的每个资源组都保留用于资源管理的CPU的百分比,该参数限制CPU相对使用率,仅当CPU资源发生争抢时有意义。

用户可以为资源组指定的最小CPU_RATE_LIMIT百分比为1,最大值为100。

Seabox数据库定义的所有资源组的CPU_RATE_LIMIT的总和超过100时,报告Warning。

节点上配置了CPU_RATE_LIMIT的所有资源组的最大CPU使用率是:

min((非保留的CPU核数 / 所有CPU核数) * 100, sc_resource_group_cpu_limit)

配置了CPU_RATE_LIMIT的资源组的CPU资源分配是弹性的,因为Seabox数据库可以将空闲资源组的CPU资源分配给更繁忙的资源组。在这种情况下,当该资源组接下来变为活动时,CPU资源被重新分配给先前空闲的资源组。如果多个资源组繁忙,则根据其CPU_RATE_LIMIT的比率为它们分配任何空闲资源组的CPU资源。例如,使用CPU_RATE_LIMIT为40%创建的资源组将分配两倍于使用CPU_RATE_LIMIT为20%的资源组的CPU资源。

绝对(强制)百分比

使用CPU_RATE_CEILING属性配置的每个资源组使用CPU的百分比绝对上限。

区别于CPU_RATE_LIMIT,绝对百分比限制下,即使系统CPU资源充足,一个资源组的CPU使用率也无法超过配置值。

CPUSET

资源组的CPUSET属性,将指定的CPU核分配给资源组。指定的CPU核必须是系统中可用的,允许重叠分配。尽管Seabox数据库按资源组独立使用不同的CPU核,但需注意的是,这些核很可能已经被系统中其它非Seabox数据库进程使用。

指定CPU核给CPUSET组时,需要考虑:

  • 使用CPUSET属性创建的资源组指定了其使用的CPU,同一个CPU核允许重复分配给多个资源组,也就是说允许多个资源组共享使用一个或多个CPU核。建议最小化配置CPUSET组,以避免CPU资源浪费。
  • 建议保留0号CPU核不分配。0号CPU核有以下特殊用法:

  • 缺省资源组要求至少有一个CPU核。当所有CPU核被分配时,Seabox数据库仍将0号CPU分配给这些缺省资源组。此时,分配了0号CPU的资源组将与缺省资源组共享CPU核。

  • 如果因为某个节点替换,且该节点资源组没有足够的CPUSET指定的CPU核重启Seabox数据库时,所有资源组自动分配给0号CPU核以避免系统启动失败。

  • 当给资源组分配CPU核时,建议使用最少可用核数。在替换Seabox数据库节点且新节点比原节点核数少时,或数据库备份后恢复到另一套节点CPU核数较少的Seabox数据库时,操作可能因CPU核数不足而失败。例如,Seabox数据库节点有16个核,分配CPU1-7是最佳建议,此时如果创建了一个分配了9号CPU的资源组,数据库恢复到8核的节点时会报错。

配置了CPUSET的资源组有较高优先级使用CPU资源。所有配置了CPUSET的资源组的最大CPU资源使用百分比为已分配CPU核数除以CPU核数的总数再乘以100。

资源组CPUSET为-1时,表示“不设置”,是一种特殊情况,表示“使用系统上所有CPU核”。

内存管理

重要说明:

  1. 本章节所述“实例”即为“executor”,一个实例对应一个executor。
  2. Seabox数据库内存统计与限制采信“悲观”假设,当程序申请(malloc)内存时,内存即被统计为“已使用(used)”,即我们“悲观”地假定这些申请的内存未来将被全部使用。所以,文中的“内存使用量”实际指“申请的内存量”,与操作系统的驻留内存(RES或RSS)没有对应关系。

内存使用量限制

实例级内存限制

为了防止Seabox数据库内存过量使用,导致seaboxsql进程被操作系统OOM杀掉,应当限值Seabox数据库的内存使用量,将潜在的被动Kill转成数据库主动的取消(Cancel)过程。

参数sc_vmem_protect_limit限值了单个executor的内存使用上限,与是否启用资源组无关。

注意:目前没有任何自动的控制机制可以控制一个节点上多个实例的内存使用总量。例如,一台物理服务器上部署了多个数据库实例(即多个executor),每个实例最大可用内存依赖于系统管理员人工评估。 为了便于配置,Seabox数据库安装时,安装程序会根据物理内存、部署拓扑情况及其它参数自动评估和设置每个实例的最大可用内存参数sc_vmem_protect_limit。

实例级内存Red Zone

与sc_vmem_protect_limit配套使用的还有个参数runaway_detector_activation_percent,两者确定的一个内存使用量“Red Zone(警戒区)”。 内存使用量Red Zone是一个范围,与是否启用资源组无关。

假设,

sc_vmem_protect_limit = 100GB;
runaway_detector_activation_percent = 90;

则,内存使用量Red Zone范围为[90GB, 100GB],下边界计算方法如下:

sc_vmem_protect_limit * runaway_detector_activation_percent / 100 = 100GB * 90 / 100 = 90GB

以上示例的Red Zone用示例图表示如下:

当实例内存使用量进入Red Zone范围,则当前实例进入“内存清理”状态。Seabox数据库根据一定的规则,主动Cancel部分正在执行的任务,通常地,内存使用量最多的任务优先被取消。

资源组内存限制

启用资源管理时,当资源组的MEMORY_LIMIT属性大于0时,表示该资源组设置了内存使用量限制,这种情况下,当该资源组内存使用量计数大于MEMORY_LIMIT时,则报查询内存超限错误。

查询级内存限制

参数sc_vmem_limit_per_query限制单个查询在一个实例上最大内存使用量,与是否启用资源组无关,默认为0,表示不限制。

如果该参数值大于0,当某个查询在一个实例上使用的内存量超过该参数值,则报查询内存超限错误。

分布式数据库中,一个查询可能会分发多个并发在同一个实例上同时执行,一个实例上同一个查询的并发任务的查询级内存使用量是共享计数的。

查询的计划内存限制(query_mem)

行文至此,我们有必要解释一下“计划内存限制”与“实际内存使用量限制”的区别:

  • 计划内存限制:主要供查询计划器使用,是我们期望的单条查询的内存使用量,是理想的期望值。
  • 实际内存使用量限制:查询执行过程中实际内存使用量限制,属于强制限制,一旦超限就会报错。

在查询执行过程中,因为某些算子的算法不能精确地控制内存使用量,此时内存使用量会超过计划值,直到实际的内存使用量达到了以上某个参数的强制限制才会报错。

Coordinator在查询开始前,根据不同情况,为当前查询确立计划内存限制(记作:query_mem):

  • 如果没有启用资源组
  • statement_mem=0,则计划器不限制内存,算子内存由work_mem限制,此时query_mem=0。
  • statement_mem>0,使用statement_mem参数值为算子推算计划内存限制,此时query_mem=statement_mem。
  • 启用了资源组
  • sc_resgroup_memory_query_fixed_mem=0:
    • 且MEMORY_LIMIT>0,则使用MEMORY_LIMIT / CONCURRENCY计算值为算子计划内存限制,此时query_mem=MEMORY_LIMIT/CONCURRENCY。
    • 且MEMORY_LIMIT=-1,则使用statement_mem参数值为算子计划内存限制,此时query_mem=statement_mem。
  • sc_resgroup_memory_query_fixed_mem>0,则使用该参数为算子计划内存限制,此时query_mem=sc_resgroup_memory_query_fixed_mem。

注意:这个过程是在Coordinator上进行的。

举个例子,假设计划内存限制query_mem=statement_mem,且statement_mem=125MB,下图示意了查询计划器根据特定算法(下文详细介绍)为某个查询推算的算子级计划内存使用量:

算子级内存限制

具体到某个查询算子的内存使用量限制,主要分两种情况:

  • 计划器为算子规划了内存限制,则算子直接使用规划的内存限制。
  • 计划器没有为算子规划内存限制,则算子直接使用work_mem参数值限制内存。

一般地,具体到算子内部实现,算子会尽可能限制内存使用量不超出计划值,超出时算子将使用“计算结果溢出到磁盘技术“,抑制内存使用量。算子实际内存使用量超出计划限制不会直接导致报错。

内存的划分与使用策略

Transaction Slot

资源组管理开启时,Seabox数据库引入了插槽(Transaction Slot,简称Slot)概念,当资源组的CONCURRENCY大于0时,该资源组将预设CONCURRENCY个Slot,每个并发占用一个Slot。 本组所有Slot被占用后,新的并发将进入等待队列,直到正在执行的并发任务执行完释放了Slot为止。Slot也是每个并发统计内存的粒度。

内存划分实例

举个例子:假设一个host可用内存为120GB,部署了4个executor(实例),每个executor平分到30GB内存,每个executor配置参数如下:

sc_resource_manager = group;
sc_vmem_protect_limit = 30GB;
runaway_detector_activation_percent = 90;

包括缺省资源组在内,共有4个资源组,各资源组的MEMORY_LIMIT和CONCURRENCY配置如下:

  groupname   | concurrency | memory_limit 
--------------+-------------+--------------
default_group | 20          | 6144         
admin_group   | 10          | -1           
system_group  | 0           | -1           
rg_sample     | 5           | 5120         

角色role1指派到了rg_sample资源组,可以推算出:

  • role1执行的单个并发查询(每个并发占用一个Transaction Slot),查询级计划内存为:5120 / 5 = 1GB。
  • 当资源组内存使用量超过5120MB时,查询报内存超限错误。
  • 当实例的使用内存量超过27GB(即,sc_vmem_protect_limit * 90 / 100 = 27GB)时,该实例内存使用量进入了Red Zone区,触发内存清理机制。

超级用户指派到了admin_group组,内存使用量不受限值(MEMORY_LIMIT<=0),直至实例的使用内存量超过27GB,触发内存清理机制。

下图示意了内存划分过程,从左到右逐级划分:

资源组内存使用顺序

启用资源组功能的情况下,按照以下顺序使用内存。

  • 普通模式下:
  • 一条查询优先使用自己私有的固定配额内存(一个Transaction Slot对应的内存配额)。
  • 如果不够,可以继续申请:
    • 如果当前资源组内存量有限制(MEMORY_LIMIT>0时),当使用量超过当前资源组的内存限制,则报内存超限错误。
    • 如果当前资源组内存量无限制,则可以继续申请内存,直至单条查询或者实例最大可用内存超限报错。
  • bypass模式下,即sc_resource_group_bypass = on时:
  • 一条查询在Coordinator节点可以使用30MB内存。
  • 一条查询在每个Executor节点可用使用10MB内存。
  • 如果还是不够,按照上述普通模式的内存限制处理超额使用的情况。
算子按内存分型

从内存使用特征角度将算子分成两大类,以区别处理:

  • 非内存密集型算子(即非内存敏感型算子):内存需求量通常较少,查询执行期间,Seabox数据库可在已申请到的内存中保留全部数据。
  • 内存密集型算子(即内存敏感型算子):内存需求量普遍较大,例如,Join或Sort等。大量数据处理时,如果不对其内存使用量进行控制,很容易导致内存使用失控。
内存使用策略
  • sc_resgroup_memory_policy

服务端参数sc_resgroup_memory_policy用于查询计划器,控制所有查询算子的内存分配策略。Seabox数据库支持资源组使用eager-free和auto内存分配两种策略。当指定为auto策略时,Seabox数据库使用资源组内存限制在算子之间分配内存,为非内存密集型算子分配固定大小内存并将剩余内存分配给内存密集型算子。当使用eager-free策略时,Seabox数据库会把已经完成处理的算子释放的内存重新分配给后续算子,从而在算子之间更优地分配内存。

  • sc_vmem_protect_segworker_cache_limit

如果一个查询处理进程消耗了超出本参数设定的内存量,那么进程处理完成后不会被缓存,以用于后续查询。有很多个连接或者空闲进程的系统可能需要削减此值以释放更多的executor内存。详见下文参数说明。

资源组内存限制策略

同一个资源组的多个用户,内存使用量受资源组的MEMORY_LIMIT(>0时)值限制,如果MEMORY_LIMIT为0或者-1,则该资源组内存使用量不受限制。

查询算子内存

按照上述内存分配策略,查询计划器为每个算子规划了内存使用量期望值。

查询算子内存溢出到磁盘

内存密集型算子比较特殊,对内存需求量很大,为了限制其内存使用量,大部分此类算子在算法实现上进行了特殊处理,当内存使用量超出计划值时,算子会将计算的中间结果以文件的形式临时溢出(保存)到磁盘(查询结束后会自动删除临时的文件),以抑制算子实际内存使用量。

低内存需求的查询性能

statement_mem设置为小值(例如10MB)可提高低内存需求查询的性能。

SET statement_mem='10MB';

从host到算子内存推算详解

本节叙述Seabox数据库如何将内存逐级进行计算,直至推算出算子级内存计划量。

Chunk

首先引入Chunk概念。字节作为内存计数单位太小了,因此,执行器内部使用Chunk作为内存最小统计单位,Chunk最小为1MB,且是2的幂次方。 在计算内存限额或者显示内存使用的统计视图中,可以看到内存的变化粒度是Chunk,会有一些误差,但不会有实质性影响。

实例级可用内存量

记作:executor_mem

是一个实例(executor)可以使用的内存量上限。假设,host可用物理内存为100GB,且Seabox数据库被允许使用这些内存,一个host上部署了4个executor。 理论上,可以将sc_vmem_protect_limit配置为:

sc_vmem_protect_limit = 100GB / 4 = 25GB

当然,这是一个极其理想的估算值,系统管理员需要根据环境的实际使用情况评估一个更合理的值。

一条查询的可用内存

记作:query_mem

查询计划器根据“查询的计划内存限制(query_mem)”小节的算法,确立一条查询的内存使用期望值。

查询的算子内存

Coordinator统一规划查询树各个算子的内存使用量。

注:具体计算策略与 sc_resnone_memory_policy(未启用资源组)或者sc_resgroup_memory_policy(启用资源组) 参数有关。

(1)非内存密集型算子

记作:nonMemIntenseOpMem

  • 如果启用了资源组,每个算子分配固定量内存,由 sc_resgroup_memory_policy_auto_fixed_mem 参数确定,默认100KB。
  • 如果没有启用资源组,每个算子分配固定量内存,由 sc_resnone_memory_policy_auto_fixed_mem 参数确定,默认100KB。

(2)内存密集型算子

记作:memIntenseOpMem

  • query_mem>0时,memIntenseOpMem = (query_mem - nonMemIntenseOpMem * 非内存密集型算子个数) / 内存密集型算子个数。
  • query_mem=0时,memIntenseOpMem = work_mem。

磁盘管理

磁盘空间使用率告警

Seabox数据库可以监视磁盘分区空间使用率,并根据配置参数在查询返回时给出告警信息。

详见sc_disk_usage_limit_warning参数说明。

IO限流

资源组管理子功能之一,本功能可以按照资源组限制磁盘的实际IO速率。

需要注意的是,资源组配置的磁盘IO限制与磁盘实际的IO速度存在正比例关系,但具体比例值与数据特征和数据库部署情况等相关。

应用程序写入文件时,操作系统会先缓存到内存里,在满足特定条件时才会实际写入磁盘,形成物理写入。

资源组管理可以通过以下参数控制WAL产生速率:

  • IO_KBPS:每秒允许产生的WAL字节数,单位:KB。
注意事项
  • 推荐只对低优先级应用限制,对高优先级应用完全不限制。
  • 更改限制值后,最多需要几十秒的时间才能生效。
  • 对于重IO的查询,性能会下降,因为限制WAL产生对应限制了物理磁盘的写入速度上限。但是,缓解了磁盘写入压力,提高了高优先级应用的响应速度。
示例
-- 创建资源组,每秒钟WAL产生速率限制为 10MB/s
CREATE RESOURCE GROUP io_rg WITH (cpu_rate_limit = 20, io_kbps = 10240);
\x
-- 查询各资源组资源使用情况
SELECT * FROM sc_toolkit.sc_resgroup_status;
-- 查询各资源组IO资源使用情况
SELECT rsgname, io_speed FROM sc_toolkit.sc_resgroup_status;

网络管理

内部数据传输限流

资源组管理子功能之一,本功能可以按照资源组限制内部数据传输的网络速率。

内部数据传输的网络速率与实际网卡速率存在正比例关系,但具体比例值与数据特征、数据库部署情况、执行的SQL等相关。

资源组管理可以通过以下参数控制内部数据传输的网络速率:

  • IC_KBPS:每秒内部数据传输的网络速率,单位:KB。
注意事项
  • 更改限制值后,最多需要几十秒的时间才能生效。
示例
-- 创建资源组,内部传输速度限制为 10MB/s
CREATE RESOURCE GROUP net_rg WITH (cpu_rate_limit = 20, ic_kbps = 10240);
\x
-- 查询各资源组资源使用情况
SELECT * FROM sc_toolkit.sc_resgroup_status;
-- 查询各资源组IO资源使用情况
SELECT rsgname, ic_speed FROM sc_toolkit.sc_resgroup_status;

队列优先级

队列优先级(QUEUE_PRIORITY)分为高、中和低三个级别,分别对应属性值2、1和0。-1表示资源组不受队列优先级限值。

队列优先级是指:高优先级的资源组有更高的获得执行资格的机会,即当高优先级的资源组有任务正在排队等待执行时,低优先的资源组将被阻挡执行(被调度执行的概率远低于高优先级组),优先调度高优先级的资源组执行。

需要说明的是,优先级是个相对关系,当高优先级有排队时,低优先级组也有被调度运行的可能,只是概率相对很小,与队列的调度时机有关。

参数sc_resource_group_max_running控制所有有优先级的资源组最大运行运行的任务数。资源组的并发数(CONCURRENCY)仍然有效。

下面是设置sc_resource_group_max_running=10时,高、中和低三个资源组各有20各并发任务,稳定状态时任务运行状态统计:

select usename, count(*) as total, count(nullif(wait, true)) as running, count(nullif(wait, false)) as wait 
from (
    select usename as usename, wait_event_type = 'ResourceGroup' as wait 
    from pg_stat_activity where usename like '%role'
    ) t 
group by usename order by usename;
   usename   | total | running | wait 
-------------+-------+---------+------
 high_role   |    20 |      10 |   10
 low_role    |    20 |       0 |   20
 middle_role |    20 |       0 |   20
(3 rows)

VE引擎资源管理

CPU资源管理

关于CPU的资源管理仍然适用于VE引擎。

内存资源管理

VE引擎的参数说明请参考VE引擎说明,这里仅给出VE常用配置参数。

ve_mem_limit_overall

VE引擎使用本参数控制单个进程VE引擎允许使用的最大内存。

这个参数用于限制VE引擎单个进程内存使用阈值,内存使用量达到该限制时,查询中断并报异常。0表示不限制。

范围[0 - 2TB],单位KB,默认0,表示不限制。

ve_mem_per_hash_table

VE引擎使用本参数控制内存溢出到磁盘的门限。

Hash类算法,诸如Hash Join和Hash聚集算子,Hash表是主要内存消费者,本参数设定单个算子Hash表内存达到阈值时,计算中间结果将被溢出到磁盘,以释放部分内存,以避免算子内存过度使用。

范围[1KB - 2TB], 单位KB,默认10GB。

ve_mem_two_level_hash_limit

对于Hash聚集算子,VE引擎可能会使用 2-level 算法来优化聚集Hash表性能,本参数用来设定聚集启用2-level算法的内存阈值。

资源管理相关配置参数

本章节所述参数不仅限于资源组管理,与资源限制相关的参数均可能被涉及。

本节为部分参数设置了“标注“,标注意义为:

  • 资源组:该参数仅适用于资源组。
  • 非公开:是一个公开的参数,通常用户不需要关注。
  • SUPERUSER:修改该参数需要需要超级用户权限。
  • 已经废弃:已经废弃的参数,手册保留了说明仅适用于旧版本。

sc_resource_manager

指示Seabox数据库当前资源管理方式。缺省为不使用资源管理(none)。

值范围 缺省 分级设置
none, group, group-v2 none local, system, restart

sc_resource_group_activate

sc_resource_managergroup或者group-v2时,可以通过配置参数sc_resource_group_activate控制资源组管理是否激活。

sc_resource_manager不同,修改sc_resource_group_activate参数值无需重启数据库(仅需要reload)。

值范围 缺省 分级设置
Boolean true system, reload

注意:

  1. sc_resource_managernone时,本参数无效。
  2. 本参数变更仅影响新事务。正在执行的事务,不受参数变更影响。

sc_resource_group_cgroup_parent

为Seabox数据库指定cgroup顶层名称,默认为空,即按照Seabox定义的规则自动命名(scdb_初始安装Seabox数据库的Linux用户名)。例如,seabox.service。

值范围 缺省 分级设置
格式为“abc.xyz”形式的字符串 "" local, system, restart

sc_vmem_protect_limit

参数限制Seabox数据库活动实例允许使用的最大内存(单位:MB),如果查询引起实例内存使用总量超出该参数值,则查询失败。本参数是一个本地的,每个数据库实例可以分别设置。

值范围 缺省 分级设置
integer 8192 local, system, restart

Seabox数据库安装时,安装程序会根据系统内存大小自动评估该参数值。系统管理员也可以根据实际情况手动配置。

注意: 1. 历史版本中,本参数仅当资源组管理关闭时生效,即资源组管理不使用该参数配置。最新版本该参数始终有效。 2. 历史版本中,该参数在coordinator上不生效。最新版本该参数coordinator上也有效。

runaway_detector_activation_percent

无论是否启用资源管理,本参数均有效。参数用于确定Seabox数据库终止查询的内存使用百分比。如果设置0或者100(即100%),则禁止内存使用超限时的自动终止查询机制。

值范围 缺省 分级设置
百分比 90 local, system, restart

Seabox数据库内部设立了一个内存Red Zone,本参数确立的内存水位线至实例可以使用的最大内存,这部分被称为Red Zone,当实例内存使用量达该区域时,实例进入runaway状态(内存清理状态),触发查询终止机制。终止哪些查询,Seabox数据库内部有一套机制,通常优先终止内存使用量最大的查询。

该参数设置Seabox数据库内存使用百分比,当内存使用率达到此比例时,则触发自动终止查询机制。

例如,假设实例可以使用的最大内存为10GB,本参数设置为90,则当内存使用量超过9GB时,触发查询终止机制。

max_query_size

设置查询SQL最大长度,单位为字节。

取值范围 默认值 设置分类
[1024B, 1GB-1B] 10MB session, reload, superuser

statement_mem

查询计划器为每个查询分配executor主机内存。为该参数分配的内存量不能超过资源组上的内存限制。

如果查询需要额外的内存,则使用磁盘上的临时溢出文件。 0表示查询计划器不使用该参数。

取值范围 默认值 设置分类
KB 0 master, session, reload

可以使用以下方法估算statement_mem配置值:

假设,
实例级内存限制:sc_vmem_protect_limit = 25GB
Red Zone比例:runaway_detector_activation_percent = 90
根据业务特征估算的期望的最大并发查询个数:max_expected_concurrent_queries = 60

则,
redzone_mem = sc_vmem_protect_limit * runaway_detector_activation_percent / 100 = 25GB * 0.9 = 22.5GB
statement_mem = redzone_mem / max_expected_concurrent_queries = 22.5GB / 60 = 0.375GB

max_statement_mem

标注:SUPERUSER。

设置查询的最大内存限制。由于将statement_mem设置得太高,有助于在查询处理期间避免executor主机上的内存不足错误。

更改max_statement_memstatement_mem时,必须先更改max_statement_mem,或者先在seaboxsql.conf文件中列出。

取值范围 默认值 设置分类
KB 2000MB master, session, reload, superuser

可以使用以下方法估算max_statement_mem配置值:

假设,
实例级内存限制:sc_vmem_protect_limit = 25GB
根据业务特征估算的期望的平均并发查询个数:average_number_concurrent_queries = 30

则,
max_statement_mem = sc_vmem_protect_limit / average_number_concurrent_queries = 25GB / 30 = 0.83GB

sc_active_backend_resqueue_length

后端允许执行事务的队列长度,即允许同时进入执行状态的最大事务个数。-1表示不限制。参数值不得为0。

注意:Seabox V21.3版本之前,0表示不限制。需要在升级时注意!

值范围 缺省 分级设置
-1, 1 - 65535 200 master, system, reload

sc_global_active_backend_resqueue_length

全局的后端允许执行事务的队列长度,即允许同时进入执行状态的最大事务个数。-1表示该参数无效。

当参数值>=0时,sc_active_backend_resqueue_length参数值无效。

本参数在SeaboxMPP多Coordinator的情况下才有实际意义,全局资源调度进程将根据每个Coordinator的当前负载情况,为每个Coordinator分配实际的“后端允许执行事务的队列长度”。所有Coordinator被分配的“后端允许执行事务的队列长度”之和不大于本参数值。

值范围 缺省 分级设置
integer -1 master, system, reload

sc_global_resource_scheduler_interval

全局资源调度进程(global resource scheduler)循环调度间隔时长,单位:ms。

在多Coordinator的情况下,全局资源调度进程将根据每个Coordinator的当前负载情况,为每个Coordinator分配实际的“后端允许执行事务的队列长度”,如果启用了资源组管理,还为每个Coordinator分配实际的资源组“最大的并发事务数”。

需要注意的是,全局资源调度本质上是一种跨Coordinator的负载均衡功能,调度不是实时的,另外,调度算法为每个Coordinator分配的配额可能与实际需求有出入。

0表示禁止全局资源调度功能(禁止启动或退出调度进程)。

值范围 缺省 分级设置
integer 10s master, system, reload

sc_active_backend_resqueue_bypass

强制绕过后端事务队列长度限制。

注意:强烈建议仅管理员执行运维或其他特殊操作时,在会话级临时设置该参数,否则后端事务队列功能将失去实际控制作用。

值范围 缺省 分级设置
Boolean false session

sc_resgroup_memory_query_fixed_mem

标注:资源组、非公开。

当该参数被设置大于0时,计划器强制使用本参数规划查询内存(即,既不使用statement_mem也不使用资源组的MEMORY_LIMIT)。0表示不使用本参数。

sc_resgroup_enable_blkio

设置Seabox数据库是否允许使用cgroup v1的blkio子系统或者cgroup v2的io控制器。

值范围 缺省 分级设置
Boolean false local, system, restart

设立此参数的原因:已知在CentOS 8以及openEuler系统上,systemd存在缺陷,systemctl daemon-reloadsystemctl enable等命令会删除blkiodevices子系统下的用户层级。 导致Seabox数据库资源组cgroup v1配置丢失,引发报错。设置此参数可以配置Seabox数据库禁止使用blkio功能,blkio功能被禁止后,Seabox部分IO相关的功能失效。

如果Seabox配置为使用cgroup v2,本参数则控制是否允许使用cgroup v2的io控制器。

注意:io_speed功能不受影响。

sc_vmem_limit_per_query

每条查询在每个executor上的最大允许使用的内存量,单位为KB。默认为0,表示不限制。

无论是否启用资源管理,均有效。

值范围 缺省 分级设置
integer 0 master, session, reload

注意:历史版本中,该参数在coordinator上不生效。最新版本该参数coordinator上也有效。

sc_vmem_protect_segworker_cache_limit

如果一个查询处理进程消耗了超出配置的内存量,那么进程处理完成后不会被cache,以用于后续查询。有很多个连接或者空闲进程的系统可能需要削减此值以释放更多的executor内存。注意,此参数是本地参数,需要为每个executor设置。

值范围 缺省 分级设置
Boolean false master, session, reload

sc_vmem_idle_resource_timeout

如果数据库会话长时间空闲,会话的资源(如共享内存)会被释放,但是仍然保持连接。这样可以允许更多的并发连接。

值范围 缺省 分级设置
任何有效的时间表达式 18s master, system, reload

sc_workfile_max_entries

每个executor的最大允许溢出的文件集(文件登记条目)个数。修改本参数需要重启数据库。

注意:文件集与物理文件不是等价的,文件集是个逻辑概念。一个文件集下可能对应一到多个物理文件,一般情况下,单个溢出文件最大1GB,超出时将拆分为多个文件。

值范围 缺省 分级设置
32 - INT_MAX 8192 local, system, restart

sc_workfile_limit_files_per_query

设置每条查询在每个executor上可以溢出的临时文件个数。0表示不限制,由操作系统控制。

值范围 缺省 分级设置
整型数 100000 master, session, reload

sc_workfile_limit_per_query

每条查询在每个executor上可以溢出的文件大小最大值,0表示不限制。

值范围 缺省 分级设置
KB 0 master, session, reload

sc_workfile_limit_per_executor

每个executor允许所有查询溢出磁盘总大小,0表示不限制。

值范围 缺省 分级设置
KB 0 local, system, restart

sc_memory_assign_policy

标注:SUPERUSER。

算子内存分配策略。

  • auto:Seabox数据库将查询计划的内存query_mem在查询算子之间分配,非内存敏感算子分配固定大小内存,剩下的分配给内存敏感算子。
  • eager_free:Seabox数据库分配内存更优化,已经执行完释放出来的内存将被重新分配给后续算子使用。
值范围 缺省 分级设置
auto, eager_free eager_free local, system, superuser, restart/reload

注:sc_resnone_memory_policysc_resgroup_memory_policy参数仅在早期版本可用。

sc_resource_group_bypass

标注:资源组

允许/禁用Seabox数据库资源组并发事务限制,缺省值是false,表示允许资源组事务限制。可以将该参数值设为true,以立即旁路一个查询不受资源组资源限制。例如,可以设置该参数值为true,以便将某个关于系统表的查询旁路不受资源组限制。

当设置该参数值为true并运行一个查询时,该查询运行环境如下:

  • 查询运行在资源组内。该查询的资源组分派不变。
  • 每个查询的内存有少量配额(Coordinator节点30MB内存,Executor节点10MB)。如果请求的内存超出了内存使用量限制,查询失败。

该参数设置可以是session级的。参数可以在一个事务或者一个函数中设置。通常地,当admin_group的并发数超限后,为避免管理员也无法执行管理命令,SUPERUSER用户在执行命令前需要设置本参数为on。

注意:强烈建议仅管理员执行运维或其他特殊操作时,在会话级临时设置该参数,否则资源组的并发限制功能将失去实际作用。

值范围 缺省 分级设置
Boolean false session

sc_resource_group_queuing_timeout

标注:资源组。

指示当因为超出并发数而导致事务排队等待时的排队超时时长(毫秒),0表示一直等待永不超时。

值范围 缺省 分级设置
0 - INT_MAX (ms) 0 master, system, session, reload

sc_resource_group_cpu_limit

标注:资源组。

指示资源组每个Seabox数据库 executor节点可以使用的CPU资源最大百分比(绝对使用率控制)。

值范围 缺省 分级设置
0.1 - 1.0 0.9 local, system, restart

sc_resource_group_cpu_priority

标注:资源组。

设置Seabox数据库进程的CPU优先级(相对于系统进程的优先级,系统进程优先级视为1)。
例如,参数设为10,当CPU资源发生争抢时,Seabox数据库进程和系统进程将按照10:1的比例争抢CPU时间片。

值范围 缺省 分级设置
1 - 100 10 local, system, restart

sc_memory_policy_auto_fixed_mem

标注:资源组、非公开。

指定非内存敏感算子内存大小,默认100KB。

注:sc_resnone_memory_policy_auto_fixed_memsc_resgroup_memory_policy_auto_fixed_mem参数仅在早期版本可用。

memory_spill_ratio(已废弃)

标注:已废弃。

设置内存敏感算子内存使用比例上限。当事务使用内存超限时,将溢出到磁盘。缺省值是资源组指派给当前活动角色的memory_spill_ratio值。可以为每个session单独设置。

参数值可以是0到100。如果设置为0,Seabox数据库将使用statement_mem参数值。

值范围 缺省 分级设置
0 - 100 20 master, session, reload

sc_resource_group_cgroup_memory(已废弃)

标注:已废弃。

指示资源组每个Seabox数据库 executor节点可以使用的最大内存(单位:MB)。

值范围 缺省 分级设置
0 - 512000 0 local, system, restart

sc_resource_group_memory_limit(已废弃)

标注:已废弃。

指示资源组每个Seabox数据库 executor节点可以使用的内存资源最大百分比。

值范围 缺省 分级设置
0.1 - 1.0 0.7 local, system, restart

当使用资源组时,内存将均分给executor主机上的活动的主executor。Seabox数据库给起主作用的主executor分配内存。即使是故障转移(failover),分配的初始内存不会改变。这就意味着,executor主机上实际使用内存可以会超出sc_resource_group_memory_limit设定的限制。

例如,假设Seabox数据库使用缺省sc_resource_group_memory_limit配置0.7,有个名为exehost1的executor主机上有4个主executor和4个镜像executor。Seabox数据库会为exehost1上每个executor指派系统内存的(0.7 / 4 = 0.17)。如果发生故障转移,exehost1有2个镜像executor故障转移成为主executor,4个原始的主executor仍然保留0.17系统内存,2个新的主executor每个分配(0.7 / 6 = 0.12)系统内存。exehost1所有内存分配:

0.7 + (0.12 * 2) = 0.94

sc_disk_usage_limit_warning

参数被设置为小于100时,每条查询在开始执行时,会检查涉及的coordinator或者executor节点的磁盘(分区)使用率,如果相关磁盘分区使用率超出本参数,则查询会报告Warning并记录日志。

参数设置为100时,不检查磁盘分区使用率,默认不检查。

值范围 缺省 分级设置
0 - 100 100 session

检查的磁盘分区包括:

  • Seabox数据库应用程序安装目录所在的磁盘分区。
  • 数据库存储所在磁盘分区(参考data_directory参数配置),不涉及表空间(table space)目录所在分区。
  • 配置参数log_directory指示的目录所在磁盘分区。

注意:

  • 每个coordinator与executor实例是独立检查,如果一个host上有多个实例,可能会报告多条相同的Warning。
  • set或者reset sc_disk_usage_limit_warning当前命令执行时返回的磁盘分区检查结果是不可靠的,从下一条命令开始,返回结果才是可靠的。

vmem_process_interrupt

在Seabox数据库查询执行期间,为查询预留vmem内存之前,启用检查中断。 在为查询保留进一步的vmem之前,请检查查询的当前会话是否具有挂起的查询取消或其他挂起的中断。 这确保了更具响应性的中断处理,包括查询取消请求。默认为关闭。

值范围 缺省 分级设置
bool类型 off master, session, reload

sc_resource_group_max_running

标注:资源组。

所有设置了优先级的资源组允许运行的最大任务数,0表示不限制。

值范围 缺省 分级设置
0 - INT_MAX 0 master, system, session, reload

多级资源组

多级资源(Hierarchical Resource Group, HRG)管理就是将原来一级的架构

      Root ResGroup
   ____|  |   |____
  |       |        |
  G1     G2       G3

变为多级(树形)架构

        Root ResGroup
     ____|  |   |____
    |       |        |
   MG1     BG2      MG3  ------- Level 1
    |                |
   MG11            BG31  ------- Level 2
  |    |
BG111  BG112             ------- Level 3

定义

多级资源组的所有资源组以树的形式组织管理,形成“资源管理树”。

变为多级架构后,分为:

  • 管理资源组(Manage ResGroup):分配资源比例,可作为业务资源组或者管理资源组的父资源组。不能指派角色,上图中MG1, MG11, MG3。

  • 业务资源组(Business ResGroup): 没有任何下级的资源组,可以指派角色,上图中的BG111, BG112, BG2, BG31。

约束关系

item Level 1 Level 2-N 附加条件 correlation
CPU_RATE_LIMIT same level
CPU_RATE_CEILING same level
CPUSET available subset (upper_level) current/upper level
CONCURRENCY <=max_connection downer <= curr <= upper current/upper level
MEMORY_LIMIT same level

原来的单级资源管理有多个属性,变为多级资源管理后,约束关系可以分为:

  • 同级约束:需要考虑本组条件,以及同级其他组
CPU_RATE_LIMIT | CPU_RATE_CEILING | MEMORY_LIMIT
  • 多级约束:考虑本组,同级其他组, 上下级组的约束
CPUSET | CONCURRENCY
  • 角色(用户)与资源组的约束关系:

  • 角色仅允许指派给叶子资源组。

  • 业务资源组的父节点只能是管理资源组,不能是业务资源组。
  • 资源管理树结构不得出现任何“环”。

语法

CREATE

CREATE RESOURCE GROUP name [PARENT=parentname] WITH ([MANAGE_GROUP=1],其他条件);

CREATE时增加了PARENT关键字,若不指定就是相当于顶层资源组

在WITH条件里增加MANAGE_GROUP=1表示是管理资源组,若不知道表示是业务资源组

例:建立一个树形结构资源组,MG1的CPU上限为50%, 它有2个子资源组,BG11的CPU上限占本级的80%,G12上限占本级的20%

Root ResGroup 100%
|
|__ MG1 50%
    |
    |__BG11 80%  (占全部CPU的40%)
    |
    |__BG12 20%
CREATE RESOURCE GROUP MG1 WITH (cpu_rate_ceiling=50,manage_group=1);
CREATE RESOURCE GROUP BG11 parent MG1 WITH (cpu_rate_ceiling=80);
CREATE RESOURCE GROUP BG12 parent MG1 WITH (cpu_rate_ceiling=20);
QUERY
-- 查看属性
-- manage_group值为0表示是管理组,0表示是业务组。
-- parentgroupid为父级资源组的ID。
SELECT * FROM sc_toolkit.sc_resgroup_config;
 groupid |   groupname   | manage_group | parentgroupid | concurrency | cpu_rate_limit | cpu_rate_ceiling | cpuset | memory_limit 
---------+---------------+--------------+---------------+-------------+----------------+------------------+--------+--------------
    6437 | default_group |            0 |             0 | 20          | 30             | -1               | -1     | -1
    6438 | admin_group   |            0 |             0 | 10          | 10             | -1               | -1     | 10
   49169 | mg1           |            1 |             0 | 20          | -1             | 50               | -1     | -1
   49170 | bg11          |            0 |         49169 | 20          | -1             | 80               | -1     | -1
   49171 | bg12          |            0 |         49169 | 20          | -1             | 20               | -1     | -1
(5 rows)

-- 查看角色与资源组对应关系
SELECT * FROM sc_toolkit.sc_resgroup_role;
         rrrolname         |  rrrsgname
---------------------------+-------------
 pg_monitor                | admin_group
 pg_read_all_settings      | admin_group
 pg_read_all_stats         | admin_group
 pg_stat_scan_tables       | admin_group
 pg_read_server_files      | admin_group
 pg_write_server_files     | admin_group
 pg_execute_server_program | admin_group
 pg_signal_backend         | admin_group
 sd_dba                    | admin_group
 sd_sso                    | admin_group
 sd_sao_owner              | admin_group
 sd_sao_etl                | admin_group
 sd_sao                    | admin_group
 r11                       | bg11
 r12                       | bg12
ALTER

ALTER 操作像单层资源组一样,支持修改7个属性,不支持修改层次继承关系

DROP

如果一个资源组有子资源组,不能删除当前资源组,需先删除子资源组

DROP RESOURCE GROUP mg1; -- ERROR:  cannot drop resource group recursively
DROP RESOURCE GROUP bg11;
DROP RESOURCE GROUP bg12;
DROP RESOURCE GROUP mg1;

建议

  • 资源管理层级不宜过深,建议不超过5层。
  • 资源组取名建议明显区分管理资源组与业务资源组,例如,使用“mg”关键字表示管理资源组。