关于资源队列的中文文档请参考:用资源队列进行工作负载管理
一、资源管理
Greenplum Database(GPDB,下文简称GP)提供的特性可以帮助你根据业务需求按照优先顺序处理和分配资源,在没有可用资源的情况下不允许启动新的查询。
你可以使用资源管理功能限制查询并发数,执行查询使用的内存量,以及查询进程的CPU相对使用量等。GP提供了两种资源管理方案:资源队列(Resource Queues)和资源组( Resource Groups)。
重要提示:
- 在RedHat 6.x 和 CentOS 6.x系统下,当启用基于资源组的负载管理时,会引起GP性能大幅退化。这是由此版操作系统的Linux内核cgroup bug导致的,CentOS 7.x 和 Red Hat 7.x系统已经修复了该问题。
- 如果在RedHat 6系统中使用GP的资源组功能,你需要将系统内核升级到2.6.32-696或更高版本。
1.1 资源管理方案
GP资源管理方案,要么选择资源队列,要么选择资源组,不能同时使用两者。
GP集群默认使用资源队列。在使用资源队列的情况下,虽然可以创建和指派资源组,但是只有在明确启用资源组的情况下,才能使用资源组方案。
资源队列与资源组之间的区别:
度量标准 | 资源队列 | 资源组 |
——– | ————————————– | ———————————————————— |
并发度 | 查询级管理 | 事务级管理 |
CPU | 指定查询优先级 | 指定CPU资源使用比例;使用Linux cgroups |
内存 | 查询级管理 | 事务级管理 |
内存隔离 | (无) | 资源组之间以及同一个资源组内部的事务间内存是隔离的 |
用户 | 仅限制非管理员用户 | 限制适用于超级用户和非管理员用户 |
排队 | 仅限没有slot的队列 | 没有slot的或者没有可用内存的队列 |
队列失败 | 如果没有足够内存,队列可能立即失败。 | 当没有共享资源组内存存在和事务需要更多内存时,查询在达到事务固定的内存限制后,可能会失败。 |
限制旁路 | 超级用户角色和特定的操作及函数不受限制 | SET、RESET和SHOW命令不受限制 |
外部组件 | (无) | 管理PL/Container的CPU和内存资源 |
1.2 使用资源组
GP可以使用资源组设定并强制限制CPU、内存和事务并发度。在定义了资源组之后,可以指派给一个或多个GP角色,或者诸如PL/Container这样的外部组件,以控制角色或者外部组件的资源使用。
当资源组指派给一个角色(基于资源组的角色)时,资源组定义的资源限制将被应用于资源组指派的所有角色。例如,限制一个指派了资源组的角色提交的所有事务最大内存使用量。
类似地,当指派一个资源组给外部组件时,资源组将作用于这个组件运行的所有实例。例如,如果给一个PL/Container外部组件创建了资源组,那么该资源组限制的内存使用量将被应用于该组件的所有运行实例。
本主题包括以下子纲要:
-
- 内存审计
- 事务并发限制
- CPU限制
- 内存限制
-
- 启用资源组
- 创建资源组
- 查询自动终止配置
- 给角色指派资源组
1.3 了解角色与组件资源组
GP支持两种类型资源组:管理角色的资源组,和管理诸如PL/Container外部组件的资源组。
资源组主要应用于管理GP不同角色查询活动数量,也可以管理每条查询使用的CPU和内存资源量。
角色资源组使用Linux cgroup管理CPU资源。GP使用一个内存审计工具vmtracker跟踪资源组的虚拟内存使用。
当执行一条查询时,GP参照资源组的限制评估查询。如果尚未达到资源组资源限制且查询不会造成资源组超出并发事务限制,则允许立即执行该查询,否则该查询进入队列排队。例如,如果并发数已经达到了资源组的上限,则随后到来的查询必须等待之前的查询执行结束才会被执行。当资源组的并发数和内存限制调整到足够大时,GP也可能恢复执行一个被挂起的查询。
角色的资源组内部,事务是按先进先出原则评估的。GP定期评估系统活动负载情况,然后重新分派资源,启动或者排队任务。
也可以使用资源组管理诸如PL/Container外部组件的CPU和内存资源。外部组件的资源组同样使用Linux cgroups管理全部组件的全部CPU和总内存资源。
注意:
GP数据库的容器化部署,如Greenplum for Kubernetes,需创建一个分层嵌套的cgroups来管理服务器各种资源。嵌套cgroups可影响GP资源组的CPU百分比、CPU核数、内存限制(外部组件除外)。数据库资源组的系统资源限制基于cgroups分组中的父级组限额。
例如,GP运行在cgroup demo下,GP的cgroups嵌套在demo组下。如果demo组配置了CPU限制为系统CPU资源的60%,且数据库资源组设置了90%的限制,则数据库使用服务器系统CPU资源的限制为54%(0.6 x 0.9)。
嵌套cgroups设置不影响基于外部组件(如PL/Container的资源组的内存限制)。外部组件的内存限制仅可用于数据库资源非嵌套cgroups时,即cgroups配置为顶层组。
关于资源组使用cgroups的配置信息,请参阅[配置与使用资源组](#1.6 配置与使用资源组)。
1.4 资源组的属性和限制
创建资源组时,需要,
- 指定资源组审计内存的方法
- 定义一组关于CPU和内存资源的限制值
资源组属性与限制:
Limit类型 | 描述 |
——————— | ———————————————————— |
MEMORY_AUDITOR | 资源组内存审计方法。缺省地,资源组使用vmtracker,外部组件使用cgroup。 |
CONCURRENCY | 最大并发数,包括活动的和空闲的事务。 |
CPU_RATE_LIMIT | 资源组的CPU使用率 |
CPUSET | 资源组保留的CPU核 |
MEMORY_LIMIT | 资源组可用内存占保留内存的百分比 |
MEMORY_SHARED_QUOTA | 分配给资源组用于运行时事务之间共享的内存资源百分比 |
MEMORY_SPILL_RATIO | 内存敏感事务的内存使用阈值。当事务内存达到此阈值,将被溢出到磁盘。 |
注:SET,RESET和SHOW命令不受资源限制。
内存审计方式
MEMORY_AUDITOR属性指示了资源组内存审计方式。指定了MEMORY_AUDITOR为“vmtracker”的资源组表示是角色资源组,而指定了MEMORY_AUDITOR为“cgroup”的资源组表示是外部组件资源组。
缺省MEMORY_AUDITOR是vmtracker。
资源组指定的MEMORY_AUDITOR决定了GP是否以及如何使用CPU和内存资源限制属性:
Limit类型 | 角色资源组 | 外部组件资源组 |
——————— | ———- | ————– |
CONCURRENCY | Yes | No;必须是0 |
CPU_RATE_LIMIT | Yes | Yes |
CPUSET | Yes | Yes |
MEMORY_LIMIT | Yes | Yes |
MEMORY_SHARED_QUOTA | Yes | 组件指定的 |
MEMORY_SPILL_RATIO | Yes | 组件指定的 |
事务并发限制
CONCURRENCY用来控制角色资源组允许的最大并发事务数。
注:CONCURRENCY限制属性不适用于外部组件资源组,外部组件资源组该值必须设置值为0。
角色的每个资源组逻辑上划分出与CONCURRENCY限制属性一样的固定数量的插槽(slot)。GP给这些插槽分配一致的确定的内存百分比。CONCURRENCY限制属性默认值是20。
当资源组的并发事务达到CONCURRENCY上限后,新提交的事务都将进入队列。此时,当一个运行中的事务完成且内存资源充足的情况下,数据库将队列中最早的事务开始执行。
可设置数据库的配置参数gp_resource_group_bypass来绕过资源组并发限制。
CPU限制
通过分配segment节点上指定的CPU核或通过标记segment节点CPU资源的百分比来给资源组配置CPU资源。GP使用CPUSET和CPU_RATE_LIMIT两个资源组限制属性来标记CPU资源的分配模式。配置资源组时只能二选一。
GP集群可以同时使用CPU资源分配的两种模式(但是一个资源组只能选择其中一种CPU资源分配模式),也可在运行中切换CPU资源分配模式。
服务端参数gp_resource_group_cpu_limit标识了每个GP segment主机上的资源组可以分配到的系统CPU资源最大百分比。该限制参数统一限定了segment主机上所有资源组的最大CPU使用率,而不考虑资源组配置的CPU分配模式。剩余的未分配CPU资源被操作系统内核及数据库辅助进程使用。gp_resource_group_cpu_limit默认值为.9(90%)。
注意:gp_resource_group_cpu_limit默认值可能不够GP运行多个负载,因此需要合理调整参数。
警告:避免将gp_resource_group_cpu_limit设置超过.9。超过.9时可能会在高负载情况下造成使用全部CPU资源,导致数据库辅助管理进程无法争抢到CPU资源。
按核分配CPU
设置CPUSET将指定的CPU核分配给资源组。指定的CPU核必须是系统中可用的,且不与其它资源组分配的核重叠。尽管GP按资源组独立使用不同的CPU核,但需注意的是,这些核有可能被系统中其它非GP进程使用。
设置CPUSET需指定一个用逗号分隔的CPU核号或核号范围的列表。必须将核号放到单引号中,例如,'1,3-4'。指定CPU核给CPUSET组时,需要考虑:
- 使用CPUSET属性创建的资源组指定了其专用CPU。如果该资源组尚未运行查询,已分配的核处于空闲状态且不能被其它资源组的查询使用。建议最小化配置SPUSET组,以避免CPU资源浪费。
- 建议保留0号CPU核不分配。0号CPU核有以下特殊用法:
- admin_group和default_group要求至少有一个CPU核。当所有CPU核被分配时,GP仍将0号CPU分配给这些缺省资源组。此时,分配了0号CPU的资源组将与admin_group、default_group共享CPU核。
- 如果因为某个节点替换,且该节点资源组没有足够的CPUSET指定的CPU核重启GP集群时,所有资源组自动分配给0号CPU核以避免系统启动失败。
- 当给资源组分配CPU核时,建议使用最少可用核数。在替换GP节点且新节点比原节点核数少时,或数据库备份后恢复到另一套节点CPU核数较少的集群时,操作可能因CPU核数不足而失败。例如,集群节点有16个核,分配CPU1-7是最佳建议,此时如果创建了一个分配了9号CPU的资源组,数据库恢复到8核的节点时会报错。
配置了CPUSET的资源组有较高优先级使用CPU资源。所有配置了CPUSET的资源组的最大CPU资源使用百分比为已分配CPU核数除以CPU核数的总数再乘以100。
当资源组设置了CPUSET时,GP不允许该资源组再使用CPU_RATE_LIMIT属性,该属性值被置为-1。
注:当GP启用基于资源管理的资源组后,必须为资源组配置CPUSET属性。
按百分比分配CPU资源
GP节点CPU被平均划为给每个节点上的segment实例。每个配置了CPU_RATE_LIMIT的资源组使用指定比例的segment实例CPU来管理资源。
CPU_RATE_LIMIT取值最小1,最大100。
GP集群中所有资源组的CPU_RATE_LIMIT之和不得超过100。
segment节点上配置了CPU_RATE_LIMIT的所有资源组的最大CPU使用率是: $$ \min (\frac {未分配的CPU核数} {所有CPU核数} * 100, gp\_resource\_group\_cpu\_limit) $$ 配置了CPU_RATE_LIMIT属性的资源组其CPU资源分配是弹性的,因为GP可以将空闲资源组的CPU资源分配给繁忙的资源组。当空闲资源组变得活跃时,CPU资源将按配置重新分配。如有多个资源组处于繁忙状态,则基于这些资源组配置的CPU_RATE_LIMIT属性,按比例将空闲资源组的CPU资源进行分配。例如,一个CPU_RATE_LIMIT为40的资源组将分配2倍于CPU_RATE_LIMIT为20的资源组的CPU资源。
当资源组设置了CPU_RATE_LIMIT,CPUSET将被置为-1。
内存限制
启用资源组时,内存使用在数据库节点、segment实例以及资源组多个层次间进行管理,也可通过角色资源组实现事务层的内存管理。
gp_resource_group_memory_limit服务端参数标识资源组在每个数据库segment主机上可分配的最大系统内存百分比,默认值为0.7(70%)。
GP节点上的可用内存资源会按该节点的segment实例平均地划分。当资源组处于活跃状态时,节点上每个的segment实例分配的内存总量为数据库可用内存乘以gp_resource_group_memory_limit参数值再除以活跃状态的segment主实例数: $$ rg\_perseg\_mem = \frac {(RAM * \frac {vm.overcommit\_ratio} {100} + SWAP) * gp\_resource\_group\_memory\_limit} {num\_active\_primary\_segments} $$ 每个资源组可分配一定比例的segment节点内存,创建资源组时,可通过参数MEMORY_LIMIT值来标识该百分比。资源组可指定的最小MEMORY_LIMIT百分比为0,最大100。MEMORY_LIMIT为0时,GP将不给资源组分配内存资源,而是使用资源组全局共享内存来满足所有内存请求。
GP集群中所有资源组指定的MEMORY_LIMIT参数和不得超过100。
基于角色资源组的额外内存限制
如果资源组内存按角色分配(MEMORY_LIMIT非零),内存被进一步分为固定和共享两部分。创建资源组时,参数MEMORY_SHARED_QUOTA的值含义为:分配给可在当前运行的事务之间共享的资源组内存百分比。这部分内存申请按照先到先得原则。一个运行中的事务可能不使用、部分使用或者全部使用MEMORY_SHARED_QUOTA内存。
MEMORY_SHARED_QUOTA最小值0,最大值100,默认80。
如上述所述,CONCURRENCY参数标识角色资源组允许并发运行事务的最大值。如果分配给资源组的固定内存(MEMORY_LIMIT非零),该内存将划分为CONCURRENCY份。每个事务执行插槽被分配了固定的、一致的资源组内存。GP将保证每个事务获得固定内存。
资源组内存分配图(注:下图与GP文档中的图略有不同,“Global Shared Memory”是我根据文档描述补充的):
当某个查询的内存使用超过事务固定的内存大小,GP将为查询分配资源组共享内存。可用于设置事务插槽的资源组内存最大值是事务固定内存和整个资源组共享内存的总和。
全局共享内存
所有资源组(包括缺省的admin_group和default_group)配置的MEMORY_LIMIT总和共同确定分配给资源组的内存百分比。如果该值小于100,GP将所有其余未分配的内存划分给资源组全局共享内存池。
仅当资源组内存审计机制为vmtracker时,资源组共享内存才可用。
当全局共享内存可用时,GP在给一个事务第一次申请固定配额内存以及适当的资源组共享内存后,分配全局共享内存。GP使用先进先出机制分配资源组全局共享内存。
注:GP记录但不主动监控资源组中事务的内存使用情况。如果某个资源组的内存使用超过固定内存配额,该资源组中的事务一旦满足以下所有条件将触发报错:
- 无可用资源组共享内存
- 无可用全局共享内存
- 事务请求额外的内存
如果保留一些内存(例如10%-20%)不分配而作为全局共享内存池,GP将更有效地利用内存资源。全局共享内存的作用还在于:应对使用内存较多的查询或不可预知的查询。
查询算子内存
多数查询的算子是非内存密集型的,这就意味着,在查询执行期间,GP可在已申请到的内存中保留数据。当内存密集型查询算子,例如,join或sort处理的大量数据无法存放在内存时,数据会溢出到磁盘。
服务端参数gp_resgroup_memory_policy控制所有查询算子的内存申请及使用,GP支持资源组使用eager-free和auto内存分配两种策略。当指定为auto策略时,GP使用资源组内存限制在算子之间分配内存,为非内存密集型算子分配固定大小内存并将剩余内存分配给内存密集型算子。当使用eager-free策略时,GP会把已经完成处理的算子释放的内存重新分配给后续算子,从而在算子之间更优地分配内存。
参数MEMORY_SPILL_RATIO表示一个事务中内存密集型算子的内存使用阈值。当达到阈值时,则溢出到磁盘。GP使用MEMORY_SPILL_RATIO限定某个事务初始分配的内存大小。
可指定MEMORY_SPILL_RATIO的参数值为0到100间的整数(含0和100),默认0。
当MEMORY_SPILL_RATIO为0时,GP将使用服务端参数statement_mem来控制查询算子初始内存。
注意:当设置MEMORY_LIMIT为0时,MEMORY_SPILL_RATIO也必须为0。
通过会话及设置服务端参数memory_spill_ratio可以有选择性地为每条查询单独设置MEMORY_SPILL_RATIO。
memory_spill_ratio参数与少量内存查询
statement_mem设置为小值(例如10MB)可提高低内存需求查询的性能。使用服务端参数memory_spill_ratio和statement_mem来覆盖每个查询初始内存设置,例如:
- snippet.sql
SET memory_spill_ratio=0; SET statement_mem='10MB';
资源组内存分配与资源组全局共享内存的使用对比
当没有为资源组预分配内存时(MEMORY_LIMIT和MEMORY_SPILL_RATIO设置为0):
- 增加资源组全局共享内存大小
- 资源组功能与资源队列相似,使用服务端参数statement_mem的值来控制查询算子的初始内存
- 资源组的任何提交执行的查询与其他资源组正在运行的查询一起以先进先出机制争抢资源组全局共享内存。
- 不保证资源组中运行的查询始终申请到内存。在高并发查询从资源组全局共享内存池消耗内存时,资源组中的查询被OOM的风险会增加。
可以考虑给这个资源组分配一些固定内存,以降低在一个重要资源组中运行查询的触发OOM风险。当为某资源组分配了固定内存而导致资源组全局共享内存降低,是降低OOM风险的折中办法。
其它内存注意事项
角色资源组通过palloc()函数记录所有GP内存申请。使用Linux malloc函数申请的内存不受资源组管理。为了保证角色资源组可精准记录内存使用情况,需要避免在用户自定义函数中使用malloc()函数申请大块内存。
1.5 使用Greenplum Command Center管理资源组
1.6 配置与使用资源组
先决条件
GP资源组使用Linux cgroups管理CPU资源。GP同样也使用cgroups管理外部组件内存资源。使用cgroups,GP隔离GP进程所在节点的CPU以及外部组件的内存使用率。这样,GP可以限制CPU和外部组件的使用。
关于cgroups详情,请参阅Linux Control Groups文档。
为了使用cgroups,请在按以下步骤完成GP集群所有节点配置:
- 如果GP运行系统环境是SuSE 11+,必须允许所有节点的swap页计数功能,并重启GP集群。内核启动参数 swapaccount 管理了SuSE 11++的swap计数,设置该参数后,必须重启系统。必须是超级用户或者有sudo权限配置内核启动参数并重启系统。
- 在超级管理员或者sudo权限下,创建GP的cgroups配置文件 /etc/cgconfig.d/gpdb.conf:
- snippet.bash
sudo vi /etc/cgconfig.d/gpdb.conf
- 添加以下内容到 /etc/cgconfig.d/gpdb.conf:
- snippet.json
group gpdb { perm { task { uid = gpadmin; gid = gpadmin; } admin { uid = gpadmin; gid = gpadmin; } } cpu { } cpuacct { } cpuset { } memory { } }
以上内容配置gpadmin用户管理的CPU、CPU计数、CPU核集和内存。GP仅在使用cgroup MEMORY_AUDITOR资源组使用内存的cgroups。
- 如果尚未安装和运行cgroups,请先在GP集群所有节点的操作系统中安装和启动cgroups服务。不同类型操作系统处理方式不同,但都需要超级用户或者sudo权限。
Redhat/CentOS 7.x:
- snippet.bash
sudo yum install libcgroup-tools sudo cgconfigparser -l /etc/cgconfig.d/gpdb.conf
Redhat/CentOS 6.x:
- snippet.bash
sudo yum install libcgroup sudo service cgconfig start
SuSE 11+:
- snippet.bash
sudo zypper install libcgroup-tools sudo cgconfigparser -l /etc/cgconfig.d/gpdb.conf
- 识别cgroup目录挂载点
- snippet.bash
grep cgroup /proc/mounts
以上命令结果的第一行就是挂载点。
- 以下命令验证安装的GP cgroups配置是否正确。使用上一步识别的挂载点替换<cgroup_mount_point>。
- snippet.bash
ls -l <cgroup_mount_point>/cpu/gpdb ls -l <cgroup_mount_point>/cpuacct/gpdb ls -l <cgroup_mount_point>/cpuset/gpdb ls -l <cgroup_mount_point>/memory/gpdb
如果这些目录都存在,且所有者是gpadmin:gpadmin,说明配置正确。
- 为了在系统重启后自动重建GP需要的cgroups层次和参数,需要配置操作系统,在系统启动时允许Linux cgroup服务守护进程cgconfig.service (Redhat/CentOS 7.x 和 SuSE 11+) or cgconfig (Redhat/CentOS 6.x)。例如,
Redhat/CentOS 7.x 和 SuSE11+:
- snippet.bash
sudo systemctl enable cgconfig.service
如果不重启系统而立即启动服务,则:
- snippet.bash
sudo systemctl start cgconfig.service
Redhat/CentOS 6.x:
- snippet.bash
sudo chkconfig cgconfig on
过程
启用资源组
GP安装后,默认使用资源队列,为了启用资源组,必须设置gp_resource_manager配置参数。
gp_resource_manager设置为“group”:
- snippet.bash
gpconfig -s gp_resource_manager gpconfig -c gp_resource_manager -v "group"
重启GP集群:
- snippet.bash
gpstop gpstart
启用资源组后,角色提交的所有事务,都受角色对应的资源组控制,包括并发度、内存和CPU。与此类似,外部组件的CPU和内存使用也受组件指定的资源库控制。
GP已经创建了两个缺省的资源组:admin_group和default_group。当启用资源组后,任何没有明确指定资源组的角色都会被指定一个缺省的资源组。SUPERUSER角色指定admin_group,而非管理员角色指定default_group。
admin_group和default_group区别如下:
限制类型 | admin_group | default_group |
——————— | ———— | ————– |
CONCURRENCY | 10 | 20 |
CPU_RATE_LIMIT | 10 | 30 |
CPUSET | -1 | -1 |
MEMORY_LIMIT | 10 | 0 |
MEMORY_SHARED_QUOTA | 80 | 80 |
MEMORY_SPILL_RATIO | 0 | 0 |
MEMORY_AUDITOR | vmtracker | vmtracker |
请记住,缺省资源组admin_group和default_group的CPU_RATE_LIMIT和MEMORY_LIMIT值影响segment主机总比例。你可能已经发现,当创建和增加资源组时,需要调整admin_group或default_group的这些限制值。
创建资源组
当为角色创建资源组时,需要通过一个名字和CPU资源分配模式。可选项包括:事务并发度限制、内存限制、共享配额和溢出率。使用 CREATE RESOURCE GROUP 命令创建新的资源组。
新创建的角色资源组必须设置CPU_RATE_LIMIT或CPUSET限制值。这些限制指示了GP分配给这个资源组的CPU资源比例。也可以指定MEMORY_LIMIT值为这个资源组保留一定量的内存资源。如果MEMORY_LIMIT为0,则GP为该资源组的所有内存请求使用全局共享的内存。
例如,创建一个名为rgroup1的资源组,CPU限制20,内存限制25,内存溢出率为20,则:
- snippet.sql
=# CREATE RESOURCE GROUP rgroup1 WITH (CPU_RATE_LIMIT=20, MEMORY_LIMIT=25, MEMORY_SPILL_RATIO=20);
CPU限制20,被rgroup1资源组的所有角色共享。类似地,内存限制25,被rgroup1资源组的所有角色共享。rgroup1使用MEMORY_AUDITOR缺省值vmtracker,以及CONCURRENCY缺省值20。
创建外部组件资源组时,必须指定CPU_RATE_LIMIT 或 CPUSET 以及 MEMORY_LIMIT限制值。还必须指定MEMORY_AUDITOR,且明确设置CONCURRENCY 为0。例如,创建一个名为rgroup_extcomp外部组件资源组,使用CPU核1,且内存限制15,则:
- snippet.sql
=# CREATE RESOURCE GROUP rgroup_extcomp WITH (MEMORY_AUDITOR=cgroup, CONCURRENCY=0, CPUSET='1', MEMORY_LIMIT=15);
ALTER RESOURCE GROUP 命令可以更新资源组设定值,例如:
- snippet.mssql
=# ALTER RESOURCE GROUP rg_role_light SET CONCURRENCY 7; =# ALTER RESOURCE GROUP exec SET MEMORY_SPILL_RATIO 25; =# ALTER RESOURCE GROUP rgroup1 SET CPUSET '2,4';
注:不能将admin_group资源组的CONCURRENCY值设置为0。
DROP RESOURCE GROUP 命令可以删除资源组。被删除的资源组不能被指派给任何角色,也不能被任何活动的或者等待的事务关联。kill所有外部组件的实例,再删除外部组件的资源组。
删除资源组:
- snippet.sql
=# DROP RESOURCE GROUP EXEC;
基于内存使用率配置查询终止方式
……
给角色指派资源组
当创建的资源组使用MEMORY_AUDITOR缺省值vmtracker,那么这个资源组可以被指派给一个或多个角色(用户)。使用CREATE ROLE 或 ALTER ROLE命令给角色指派资源组。如果角色没有被指派资源组,那么超级用户角色缺省指派admin_group资源组,非管理角色缺省指派default_group资源组。
使用CREATE ROLE 或 ALTER ROLE命令命令给角色指派资源组,例如:
- snippet.sql
=# ALTER ROLE bill RESOURCE GROUP rg_light; =# CREATE ROLE mary RESOURCE GROUP EXEC; =# CREATE ROLE fairyfar WITH SUPERUSER CREATEDB CREATEROLE LOGIN REPLICATION RESOURCE GROUP rgroup1;
一个资源组可以指派给一个或多个角色。如果已经定义了角色层级关系,那么指派给父级角色的资源组不会传递给下一个层级的角色组。
注:外部组件资源组不能指派给角色。
把NONE指派给角色,可以将资源组从角色中移除并使用缺省资源组。例如:
- snippet.sql
=# ALTER ROLE mary RESOURCE GROUP NONE;
1.7 监视资源组状态
监视资源组与查询涉及以下主题:
查看资源组限制
gp_toolkit的gp_resgroup_config系统视图,可以显示资源组的当前限制值。显示所有资源组的限制:
- snippet.sql
=# SELECT * FROM gp_toolkit.gp_resgroup_config;
查看资源组查询状态核CPU/内存使用率
gp_toolkit的gp_resgroup_status系统视图,可以显示资源组状态和活度。该视图显示运行中的和正在排队的事务个数,也可以显示资源组的CPU real-time和内存使用率。方法如下:
- snippet.sql
=# SELECT * FROM gp_toolkit.gp_resgroup_status;
显示每个host的资源组CPU/内存使用率:
- snippet.sql
=# SELECT * FROM gp_toolkit.gp_resgroup_status_per_host;
显示每个segment的资源组CPU/内存使用率:
- snippet.sql
=# SELECT * FROM gp_toolkit.gp_resgroup_status_per_segment;
查看资源组指派的角色
执行以下查询,查看分派给角色的资源组:
- snippet.sql
=# SELECT rolname, rsgname FROM pg_roles, pg_resgroup WHERE pg_roles.rolresgroup=pg_resgroup.oid;
查看资源组正在运行和挂起的查询
- snippet.sql
=# SELECT query, waiting, rsgname, rsgqueueduration FROM pg_stat_activity;
pg_stat_activity显示有关用户/角色发起的查询。使用诸如PL/Container外部组件的查询由两个部分组成:GP数据库内的查询操作和运行在PL/Container实例中的UDF。GP处理指派了资源组的角色发起的查询,UDF运行在指派了资源的PL/Container实例。后来者不会出现在pg_stat_activity视图,GP不会洞察诸如PL/Container这样的外部组件运行实例如何管理内存。
取消资源组内正在执行或者排队的事务
例如,执行以下查询语句,查看所有资源组当前全部活动或者等待的语句。如果查询返回空集,则没有任何资源组相关的事务正在执行或者排队。
- snippet.sql
=# SELECT rolname, g.rsgname, pid, waiting, state, query, datname FROM pg_roles, gp_toolkit.gp_resgroup_status g, pg_stat_activity WHERE pg_roles.rolresgroup=g.groupid AND pg_stat_activity.usename=pg_roles.rolname;
执行结果样例:
- snippet.sql
rolname | rsgname | pid | waiting | state | query | datname ---------+----------+---------+---------+--------+-------------------------+--------- sammy | rg_light | 31861 | f | idle | SELECT * FROM mytesttbl; | testdb billy | rg_light | 31905 | t | active | SELECT * FROM topten; | testdb
这个查询结果中有pid,假设要取消pid为31905的处理进程,可以这样:
- snippet.sql
=# SELECT pg_cancel_backend(31905);
可以给pg_cancel_backend指定第2个参数用来备注说明为什么取消该进程。
注:请勿使用KILL命令终止GP进程。
1.8 查询迁移到其它资源组
超级用户可以使用gp_toolkit.pg_resgroup_move_query()函数将一个正在运行的查询(无需停止该查询)从一个资源组迁移到另一个资源组。这样可以将一个长查询迁移到一个资源充足的资源组继续执行。
注:可以迁移一个活动的或者正在执行的查询,但是不能迁移一个排队或者挂起中的查询。
pg_resgroup_move_query()需要提供进程pid和目标资源组名称,函数原型如下:
- snippet.sql
pg_resgroup_move_query( pid int4, group_name text );
1.9 资源组常见问题
CPU
- 为什么CPU利用率低于资源组配置的CPU_RATE_LIMIT?
可能因为资源组执行的查询和分片比较少,执行进程使用的系统CPU资源不多。
- 为什么CPU使用率会高于资源组配置的CPU_RATE_LIMIT?
这个情形可有以下原因:
- 当其它资源组空闲时,这个资源组使用了更多的CPU超过设定的CPU_RATE_LIMIT。此时,GP会将空闲资源组的资源分配给繁忙资源组使用。这是资源组的CPU突发特性(CPU burst)。
- 操作系统的CPU调度可能引发CPU使用率陡增,然后再回落。如果是这种情况,那么可以统计一段时间(例如5分钟)CPU平均使用率,以确定CPU利用率高于配置的限制值。