使用资源队列

使用资源队列

使用Greenplum数据库的工作负载管理根据业务需求对查询按照优先权分配资源,并且在资源不可用时阻止查询开始。

资源队列是用来管理Greenplum数据库系统中并行的程度的工具。你可以使用CREATE RESOURCE QUEUESQL声明创建资源队列这一数据库对象,你可以用资源队列来管理可能并行执行的活动查询, 控制它们的内存使用量,以及队列中的相对排序。资源队列同时也可以防止查询消耗太多资源进而降低系统性能。

每个数据库角色都与一个单个资源队列关联;多个角色可以共享同一个资源队列,使用RESOURCE QUEUE 中的CREATE ROLEALTER ROLE来将角色分配到资源队列中。如果没有指定资源队列, 则角色将会自动被关联到默认资源队列pg_default

当用户提交了一个要执行的查询时,资源队列会根据其限制对查询进行评估,若该查询所需的资源没有超过限制, 它将会立即执行;若超过了限制(例如,如果目前所有活动声明槽位都已被占用),该查询则必须等到队列资源有 空闲时才能执行。对查询的评估将遵从先进先出的原则。如果启用了查询优先权,则将会预估系统当前的负载并根据 查询优先权(参考优先权如何起作用)进行资源分配。拥有SUPERUSER属性 的角色将会不受资源队列限制的限制,无论何时,超级用户的查询都会无视其所在资源队列的限制并立即执行。

Figure 1. 资源队列进程

资源队列会将资源需求相似的查询合并为Class,管理员应该根据组织中不同种类的负载创建资源队列。例如,参考以下不同的服务级别 ,用户需要根据其所对应的的查询的Class创建资源组:
  • ETL查询
  • 报告查询
  • 执行查询
拥有以下特性的资源组:
MEMORY_LIMIT
队列(每个Segment)中所有查询所使用的的内存的量。例如,对ETL查询设置2GB的MEMORY_LIMIT, 这样每个Segment里的ETL查询最多使用2GB的内存。
ACTIVE_STATEMENTS
队列中槽位的数量;一个队列中最大可并行数,当所有槽位都占用时,新的查询必须等待。默认每个查询使用 等量的内存,。
例如,pg_default资源组的ACTIVE_STATEMENTS为20。
PRIORITY
查询使用的相对CPU使用量,可以设置为以下级别:LOWMEDIUMHIGHMAX。默认级别是MEDIUM,查询优先权的机制会监控系统中所有正在运行的查询的CPU使用量, 并根据其优先权别来调整其CPU使用量。例如,你可以为执行资源队列设置MAX优先权,为其他 查询设置MEDIUM优先权,确保执行查询可以获得比较多的CPU资源。
MAX_COST
查询计划消耗限制。
Greenplum数据优化器会为每个查询分配数字型消耗,如果该消耗超过了资源队列的MAX_COST的值,该查询就会被拒绝。
Note: GPORCA和Postgres查询优化器使用不同的查询消耗模型,因此同一个查询可能会得出不同的消耗,Greenplum数据库资源队列资源管理模式不会 采用GPORCA或Postgres优化器得出的消耗,而是使用根据优化器直接返还的消耗来限制查询。

当基于资源队列的资源管理系统激活时,会使用MEMORY_LIMITACTIVE_STATEMENTS限制资源, 而不是配置基于消耗的限制。因为即便是使用GPORCA的时候,Greenplum数据库仍然可能会在特定查询中使用Postgres查询优化器从而导致未知的结果。

Greenplum数据库系统默认配置有一个默认资源队列,名为pg_defaultpg_default资源队列的ACTIVE_STATEMENTS 设置数值为20,没有MEMORY_LIMITMAX_COSTPRIORITY为中。这意味所有查询都会被接受并立即执行,没有优先权划分 和内存限制;但是并行的查询最多是20个。

一个资源队列所允许的并行查询的数量由是否有设置MEMORY_LIMIT决定:

  • 如果一个资源队列没有设置MEMORY_LIMIT的话,每个资源所分配到的内存大小就是statement_mem的服务器配置参数,一个资源队列的可用内存大小是根据statement_memACTIVE_STATEMENTS的计算结果。
  • 当资源队列有设置MEMORY_LIMIT时,资源队列中可以并行执行的查询数将会受到该队列的可用内存限制。

提交到系统中的查询将会被分配一定量的内存,且系统会对其生成一个查询计划树。计划树的每个节点都是运算符,例如排序连接和哈希连接。每个运算符都是单独的执行线程,且被分配到了总陈述说明内存中的 一部分(至少100KB)。如果计划中含有大量的运算符,运算符所需的最小内存大小可能会超过可用内存,则该查询会因内存不足而被拒绝。运算符会确定能否使用分配到的内存量完成任务,否则就会 采取spill to disk的处理方式。这种分配和控制每个运算符使用的内存大小的机制被称为内存配额

并不是所有提交到资源队列的SQL声明都会受到队列限制的评估,默认只会评估SELECTSELECT INTOCREATE TABLE AS SELECTDECLARE CURSOR声明。如果服务器配置的resource_select_only参数为off,那么INSERTUPDATEDELETE声明也会受评估。

与此同时,在执行EXPLAIN ANALYZE命令期间跑的SQL声明也会被资源队列排除。

资源队列示例

默认资源队列pg_default允许最多20个活动查询平分内存以并行执行。一般来说这是不足以满足生产环境下的资源需求的。为了确保系统能够满足性能期望,用户可以定义查询的组并 对其分配拥有相应的并行量、内存以及CPU的资源队列。

如下展示了一个示例Greenplum数据库系统(gp_vmem_protect_limit为8GB)的资源队列的配置:
Figure 2. 资源队列配置示例
该示例有三个不同属性和服务等级协议的组,各个有对应的资源队列。其中预留有一部分内存作为冗余。
资源队列名 活动声明 内存限制 每个查询的内存
ETL 3 2GB 667MB
报告 7 3GB 429MB
执行 1 1.4GB 1.4GB

队列所分配的内存总量为6.4GB,也就是说gp_vmem_protect_limit服务器配置参数所定义的总Segment内存的80%。剩余的20%是为了那些可能会需要更多内存的 运算符和查询所预留的。

关于命令语法帮助和详细参考信息请见Greenplum数据库参考指南中的CREATE RESOURCE QUEUECREATE/ALTER ROLE语句。

内存限制如何工作

一个资源队列上的MEMORY_LIMIT为一个Segment实例设置通过该队列提交的所有活动查询可以消耗的最大内存量。拨给一个查询的内存量是队列内存限制除以活动语句限制(将内存限制与基于语句的队列而不是基于代价的队列)。例如,如果一个队列的内存限制是2000MB而活动语句限制是10,每个通过该队列提交的查询会默认拿到200MB内存。可以以每个查询为基础使用statement_mem服务器配置参数覆盖默认的内存分配(最高到队列内存限制)。一旦一个查询开始执行,它会在队列中保持分拨给它的内存直至完成,即便在执行中它实际消耗的内存比分配到的内存少也是如此。

用户可以使用statement_mem 服务器配置参数来覆盖当前资源队列设置的内存限制。在会话级别,用户可以增加statement_mem,最高到资源队列的MEMORY_LIMIT。这将允许个别查询使用分配给整个队列的所有内存而不影响其他资源队列。

statement_mem的值会被max_statement_mem配置参数(是一个超级用户参数)覆盖。对于一个设置有MEMORY_LIMIT的资源队列中的查询,statement_mem的最大值是min(MEMORY_LIMIT, max_statement_mem)。当一个查询被允许进入时,分配给它的内存会被从MEMORY_LIMIT中减去。如果MEMORY_LIMIT被耗尽,同一个资源队列中的新查询必须等待。即使ACTIVE_STATEMENTS还没有达到时也会发生这种事情。注意只有当statement_mem被用来覆盖资源队列分配的内存时才会发生这种情况。

例如,考虑一个名为adhoc的队列,它有下列设置:
  • MEMORY_LIMIT 为 1.5GB
  • ACTIVE_STATEMENTS 为 3
默认每个被提交到队列的语句会被分配500MB内存。现在考虑下列一系列事件:
  1. 用户ADHOC_1提交查询Q1,并且把STATEMENT_MEM覆盖为800MB。Q1语句被准许进入系统。
  2. 用户ADHOC_2提交查询Q2,使用默认的500MB。
  3. Q1Q2仍在运行时,用户ADHOC3提交查询Q3,使用默认的500MB。

查询Q1Q2已经用掉了队列的1500MB中的1300MB。因此,Q3在能运行前必须等待Q1Q2完成。

如果在一个队列上没有设置MEMORY_LIMIT,查询都被准许进入,直到所有的ACTIVE_STATEMENTS槽被用尽,并且每个查询可以设置一个任意高的statement_mem这可能导致资源队列使用无限量的内存。

更多有关在资源队列上配置内存限制以及其他内存利用控制的信息,请见创建带有内存限制的队列.

statement_mem和低内存查询

经实践发现设置了低statement_mem参数(比如1-3MB的范围内)的低内存需求的查询会有更好的性能表现。在单个查询的基础上使用statement_mem服务器配置参数来覆盖队列的设置。例如:
SET statement_mem='2MB';

优先权如何起作用

资源队列的PRIORITY设置与MEMORY_LIMITACTIVE_STATEMENTS设置不同,后两者决定一个查询是否将被准许进入该队列并且最终被执行。PRIORITY设置对于活动查询适用。活动查询会按照其所在资源队列的优先权设置来共享可用的CPU资源。当一个来自高优先权队列的语句进入到活动运行语句分组中时,它可以得到可用CPU中较高的份额,同时也降低了具有较低优先权设置队列中已经在运行的语句得到的份额。

查询的相对尺寸或复杂度不影响CPU的分配。如果一个简单的低代价的查询与一个大型的复杂查询同时运行,并且它们的优先权设置相同,它们将被分配同等份额的可用CPU资源。当一个新的查询变成活动时,CPU份额将会被重新计算,但是优先权相等的查询仍将得到等量的CPU。

例如,管理员创建三个资源队列:adhoc用于业务分析师提交的正在进行的查询,reporting用于计划的报表任务,而executive用于行政用户角色递交的查询。由于分析师可能临时提交查询,而这些查询的资源需求是不可预测的,管理员想要确保计划的报表任务不会受到这类查询的严重影响。还有,管理员想要确保行政角色递交的查询会被分配相当份额的CPU。相应地,资源队列的优先权被设置如下:
  • adhoc — 低优先权
  • reporting — 高优先权
  • executive — 最大优先权

在运行时,活动语句的CPU份额由这些这些优先权设置决定。如果来自报表队列的查询1和2同时运行,它们有相等份额的CPU。当一个临时查询变成活动时,它会索取一个较小份额的CPU。报表查询所使用的准确份额会被调整,但仍然保持相等,因为它们的优先权设置相等:

Figure 3. 根据优先权重新调整CPU份额

Note:

这些图中显示的百分数都是近似值。高、低和中优先权队列的CPU使用并不总是准确地用这些比例计算出来。

当一个行政查询进入到运行语句组中时,CPU使用会被调整以说明其最大优先权设置。它可能是一个堪比分析师和报表查询的简单查询,但直到它完成前,它都将要求最大份额的CPU。

Figure 4. 为最大优先权查询重新调整CPU份额

更多有关设置优先权的命令的信息,请见设置优先级.

启用负载管理的步骤

在Greenplum数据库中启用并且使用负载管理涉及下列高层任务:

  1. 配置负载管理,见配置负载管理.
  2. 创建资源队列并且在其上设置限制。见创建资源队列 and 修改资源队列.
  3. 把队列分派给一个或者更多用户角色。见指派角色(用户)到资源队列.
  4. 使用负载管理系统视图来监控并且管理资源队列。见检查资源队列状态.

配置负载管理

在安装Greenplum数据库时默认会启用资源调度,资源调度对所有角色都是必需的。默认的资源队列pg_default的活动语句限制是20,没有内存限制和中等的优先权设置。为各种类型的负载创建资源队列。

配置负载管理

  1. 下列参数用于资源队列的一般配置:
    • max_resource_queues - 设置资源队列的最大数量。
    • max_resource_portals_per_transaction - S设置每个事务允许同时打开的游标的最大数量。注意一个打开的游标将在资源队列中占有一个活动查询槽。
    • resource_select_only - 如果被设置为on,那么SELECTSELECT INTOCREATE TABLE ASSELECTDECLARE CURSOR命令会被评估。如果被设置为offINSERTUPDATEDELETE也将被评估。
    • resource_cleanup_gangs_on_wait - 在资源队列中取得一个槽之前清除空转的Segment工作者进程。
    • stats_queue_level - 在资源队列使用上启用统计信息收集,然后可以通过查询pg_stat_resqueues系统视图来查看收集到的信息。
  2. 下列参数与内存利用有关:
    • gp_resqueue_memory_policy - 启用Greenplum数据库的内存管理特性。 在

      Greenplum数据库4.2和其后的版本中,分布算法eager_free 会利用并非所有操作符都会同时执行这一事实。查询计划被划分成阶段并且Greenplum数据库会饥渴地在上一阶段执行结束时释放分配给上一阶段的内存,然后将释放出来的内存饥渴地分配给新的阶段。

      当被设置为none时,内存管理与4.1之前Greenplum数据库发行版相同。当被设置为auto时,查询内存使用由statement_mem和资源队列内存限制所控制。

    • statement_memmax_statement_mem - 被用来在运行时给一个特定查询分配内存(覆盖资源队列指派的默认分配)。max_statement_mem被数据库超级用户设置以防止常规数据库用户过度分配。
    • gp_vmem_protect_limit - 设置所有查询处理能消耗的上界并且不应超过Segment主机的物理内存量。当一台Segment主机在查询执行时达到这一限制,导致超过限制的查询将被取消。
    • gp_vmem_idle_resource_timeoutgp_vmem_protect_segworker_cache_limit -被用来释放Segment主机上由闲置数据库进程持有的内存。管理员可能想要在有大量并发的系统上调整这些设置。
    • shared_buffers - 设置Greenplum服务器实例用作共享内存缓冲区的内存量。这个设置必须至少为128千字节并且至少为16千字节乘以max_connections。该值不能超过操作系统共享内存最大分配请求尺寸,该尺寸由Linux上的shmmax控制。推荐的OS内存设置请见 Greenplum 数据库安装指南
  3. 下列参数与查询优先有关。注意下列参数都是本地参数,意味着它们必须在Master和所有Segment的postgresql.conf文件中设置:
    • gp_resqueue_priority - 查询优先特性默认被启用。
    • gp_resqueue_priority_sweeper_interval - 设置所有活动语句重新计算CPU使用的时间间隔。这个参数的默认值应该足够用于通常的数据库操作。
    • gp_resqueue_priority_cpucores_per_segment - 指定每个Segment实例分配的CPU核数。Master和Segment的默认值是4。对于Greenplum Data Computing Appliance Version 2,Segment的默认值是4而Master默认值是25。

      每台主机会在其自己的postgresql.conf文件中检查这个参数的值。这个参数也影响Master节点,在Master节点上它应该被设置为一个反映CPU核数更高比率的值。例如,在每台主机有10个CPU核以及4个Segment的集群上,用户可以为gp_resqueue_priority_cpucores_per_segment指定这些值:

      为Master和后备Master指定10。通常,在Master主机上只有Master实例。

      为Segment主机上的每个Segment实例指定2.5。

      如果参数值未被设置正确,要么是CPU可能不会被完全利用,要么是查询优先可能无法按照预期工作。例如,如果Greenplum数据库集群在Segment主机上每个CPU核低于一个Segment实例,确保要相应地调整这个值。

      实际的CPU核利用取决于Greenplum数据库并行化查询的能力以及执行查询要求的资源。

      注意:操作系统任何可用的CPU核都会被包括在CPU核数中。例如,虚拟CPU核会被包括在CPU核数中。

  4. 如果用户希望查看或者更改任何负载管理参数值,可以使用gpconfig 工具。
  5. 例如,要查看一个特定参数的设置:
    $ gpconfig --show gp_vmem_protect_limit
    
  6. 例如,要在所有的Segment实例上设置一个值并且在Master上设置一个不同的值:
    $ gpconfig -c gp_resqueue_priority_cpucores_per_segment -v 2 -m 8
    
  7. 重启Greenplum数据库让配置更改生效:
    $ gpstop -r
    

创建资源队列

创建一个资源队列涉及到给它一个名称、设置一个活动查询限制并且可选地在该资源队列上设置一个查询优先权。使用CREATE RESOURCE QUEUE命令来创建新的资源队列。

创建带有活动查询限制的队列

带有ACTIVE_STATEMENTS设置的资源队列会限制指派给该队列的角色所执行的查询数量。例如,要创建一个名为adhoc且活动查询限制为3的资源队列:

=# CREATE RESOURCE QUEUE adhoc WITH (ACTIVE_STATEMENTS=3);

这意味着对于所有被分配到adhoc资源队列的角色,在任意给定时刻只能有三个活动查询被运行在这个系统上。如果这个队列已经有三个查询在运行并且一个角色在该队列中提交第四个查询,则第四个查询只有等到一个槽被释放出来后才能运行。

创建带有内存限制的队列

带有MEMORY_LIMIT设置的资源队列控制所有通过该队列提交的查询的总内存。总内存不应超过每个Segment可用的物理内存。以每个Segment为基础,设置MEMORY_LIMIT为90%的可用内存。例如,如果一台主机有48GB物理内存和6个Segment实例,那么每个Segment实例可用的内存是8GB。可以为单个队列按照0.90*8=7.2 GB来计算推荐的MEMORY_LIMIT。如果在系统上创建有多个队列,它们的总内存限制加起来也必须为7.2 GB。

在与ACTIVE_STATEMENTS联合使用时,每个查询被分配的默认内存量为:MEMORY_LIMIT /ACTIVE_STATEMENTS。在与MAX_COST联合使用时,每个查询被分配的默认内存量为:MEMORY_LIMIT * (query_cost / MAX_COST)。将 MEMORY_LIMITACTIVE_STATEMENTS而不是与MAX_COST一起使用。

例如,要创建一个活动查询限制为10且总内存限制为2000MB的资源队列(每个查询将在执行时被分配200MB的Segment主机内存):

=# CREATE RESOURCE QUEUE myqueue WITH (ACTIVE_STATEMENTS=20, 
MEMORY_LIMIT='2000MB');

可以使用statement_mem服务器配置参数针对每个查询覆盖默认的内存分配,前提是没有超过MEMORY_LIMIT或者max_statement_mem 。例如,要对一个特定查询分配更多内存:

=> SET statement_mem='2GB';
=> SELECT * FROM my_big_table WHERE column='value' ORDER BY id;
=> RESET statement_mem;

作为一种一般性的指导方针,对于所有资源队列的MEMORY_LIMIT不应超过一台Segment主机的物理内存量。如果负载在多个队列之间交错安排,超额分配一些内存可能是OK的,但要记住,如果执行期间Segment主机的内存限制(gp_vmem_protect_limit)被超过,查询可能会被取消。

设置优先级

为了控制一个资源队列对可用CPU资源的消耗,管理员可以指派一个合适的优先级。当高并发导致对CPU资源的竞争时,与较高优先权资源队列相关的查询和语句将会比较低优先权的查询和语句得到更大份额的可用CPU。

优先权设置使用命令CREATE RESOURCE QUEUEALTER RESOURCE QUEUEWITH参数创建或修改。例如,要为adhocreporting队列指定优先权设置,管理员会使用下列命令:

=# ALTER RESOURCE QUEUE adhoc WITH (PRIORITY=LOW);
=# ALTER RESOURCE QUEUE reporting WITH (PRIORITY=HIGH);

要以最大优先权创建executive队列,管理员可以使用下列命令:

=# CREATE RESOURCE QUEUE executive WITH (ACTIVE_STATEMENTS=3, PRIORITY=MAX);

当查询优先特性被启用时,如果没有显式地指派,默认会为资源队列给出一个MEDIUM优先权。更多有关运行时如何评估优先权设置的信息,请见优先权如何起作用.

Important: 为了在活动查询负载上实施资源队列优先级,用户必须通过设置相关服务器配置参数来启用查询优先特性。请见配置负载管理.

指派角色(用户)到资源队列

一旦创建了一个资源队列,用户必须把角色(用户)指派到它们合适的资源队列。如果没有显式地把角色指派给资源队列,它们将进入默认资源队列pg_default。默认资源队列的活动语句限制是20,没有代价限制,优先权设置是中等。

使用ALTER ROLE或者CREATE ROLE命令来指派角色到资源队列。例如:

=# ALTER ROLE name RESOURCE QUEUE queue_name;
=# CREATE ROLE name WITH LOGIN RESOURCE QUEUE queue_name;

任一给定时间,一个角色只能被指派给一个资源队列,因此用户可以使用ALTER ROLE命令来初始指派角色的资源队列或者更改角色的资源队列。

资源队列必须按逐用户的方式指派。如果有一个角色层次(例如,组级别角色),那么把资源队列指派给组将不会传播到组中的用户。

超级用户总是被免除资源队列限制。超级用户查询将总是被运行,而不管它们被指派的队列上的限制。

从资源队列移除角色

所有用户都必须被指派到资源队列。如果没有被显式指派到一个特定队列,用户将会进入到默认的资源队列pg_default。如果用户想要从一个资源队列移除一个角色并且把它们放在默认队列中,可以将该角色的队列指派改成none。例如:

=# ALTER ROLE role_name RESOURCE QUEUE none;

修改资源队列

在资源队列被创建后,用户可以使用ALTER RESOURCE QUEUE命令更改或者重置队列限制。用户可以使用DROP RESOURCE QUEUE命令移除一个资源队列。要更改指派到资源队列的用户,请见指派角色(用户)到资源队列.

修改资源队列

ALTER RESOURCE QUEUE命令更改资源队列的限制。要更改一个资源队列的限制,可以为该队列指定想要的新值。例如:

=# ALTER RESOURCE QUEUE adhoc WITH (ACTIVE_STATEMENTS=5);
=# ALTER RESOURCE QUEUE exec WITH (PRIORITY=MAX);

要重置活动语句或者内存限制为没有限制,输入值-1。要重置最大查询代价为无限制,输入值-1.0。例如:

=# ALTER RESOURCE QUEUE adhoc WITH (MAX_COST=-1.0, MEMORY_LIMIT='2GB');

用户可以使用ALTER RESOURCE QUEUE命令更改一个资源队列相关查询的优先权。例如,要把一个队列设置为中等优先级:

ALTER RESOURCE QUEUE webuser WITH (PRIORITY=MIN);

删除资源队列

DROP RESOURCE QUEUE命令可以删除资源队列。要删除一个资源队列,该队列不能有指派给它的角色,也不能有任何语句在其中等待。关于清空一个资源队列的指导请见从资源队列移除角色从资源队列清除等待语句。要删除一个资源队列:

=# DROP RESOURCE QUEUE name;

检查资源队列状态

查看队列中的语句和资源队列状态

The gp_toolkit.gp_resqueue_status视图允许管理员查看一个负载管理资源队列的状态和活动。对于一个特定资源队列,它展示有多少查询在等待运行以及系统中当前有多少查询是活动的。要查看系统中创建的资源队列、它们的限制属性和当前状态:

=# SELECT * FROM gp_toolkit.gp_resqueue_status;

查看资源队列统计信息

如果想要持续跟踪资源队列的统计信息和性能,可以为资源队列启用统计收集。这可以通过在Master的postgresql.conf文件中设置下列服务器配置参数实现:

stats_queue_level = on

一旦统计收集被启用,用户可以使用pg_stat_resqueues系统视图来查看在资源队列使用上收集的统计信息。注意启用这一特性确实会引发一点点性能开销,因为每个通过资源队列提交的查询都必须被跟踪。可以先在资源队列上启用统计收集用于初始的诊断和管理规划,然后再连续使用中禁用该特性。

更多有关Greenplum数据库中收集统计信息的内容,可参考PostgreSQL文档中的统计收集器部分。

查看指派到资源队列的角色

要查看指派给资源队列的角色,执行下列在pg_rolesgp_toolkit.gp_resqueue_status系统目录表上的查询:

=# SELECT rolname, rsqname FROM pg_roles, 
          gp_toolkit.gp_resqueue_status 
   WHERE pg_roles.rolresqueue=gp_toolkit.gp_resqueue_status.queueid;

用户可能想用这个查询创建一个视图来简化未来的查询。例如:

=# CREATE VIEW role2queue AS
   SELECT rolname, rsqname FROM pg_roles, pg_resqueue 
   WHERE pg_roles.rolresqueue=gp_toolkit.gp_resqueue_status.queueid;

然后就可以只查询该视图:

=# SELECT * FROM role2queue;

查看资源队列的等待查询

当资源队列的一个槽被使用时,它被记录在pg_locks系统目录表中。在其中用户可以看到所有资源队列的所有当前活跃的以及在等待的查询。要检查被放入队列中的语句(甚至不在等待的语句),用户还可以使用gp_toolkit.gp_locks_on_resqueue视图。例如:

=# SELECT * FROM gp_toolkit.gp_locks_on_resqueue WHERE lorwaiting='true';

如果这个查询不返回结果,那就意味着当前没有语句在资源队列中等待。

从资源队列清除等待语句

在某些情况下,用户可能想要从资源队列中清除等待的语句。例如,用户可能想移除在队列中等待但还未被执行的语句。用户可能还想停止已经被启动但是执行时间太久的查询,或者是在事务中闲置并且占据其他用户所需的资源队列槽的查询。要做到这一点,用户必须标识出想要清除的语句,确定它的进程ID(pid),然后使用pg_cancel_backend和进程ID来结束该进程(如下所示)。可以选择对被结束的进程发送一个消息来告诉用户原因,该消息作为第二个参数传入。

例如,要查看在所有资源队列中当前活动的或者在等待的语句,运行下列查询:

=# SELECT rolname, rsqname, pid, granted,
          current_query, datname 
   FROM pg_roles, gp_toolkit.gp_resqueue_status, pg_locks,
        pg_stat_activity 
   WHERE pg_roles.rolresqueue=pg_locks.objid 
   AND pg_locks.objid=gp_toolkit.gp_resqueue_status.queueid
   AND pg_stat_activity.procpid=pg_locks.pid
   AND pg_stat_activity.usename=pg_roles.rolname;

如果这个查询不返回结果,那就意味着当前没有语句在资源队列中等待。例如,下面的资源队列在结果中有两个语句:

rolname | rsqname |  pid  | granted |     current_query      | datname 
----------------------------------------------------------------------- 
  sammy | webuser | 31861 | t       | <IDLE> in transaction  | namesdb
  daria | webuser | 31905 | f       | SELECT * FROM topten;  | namesdb

使用这一输出来标识出想要从资源队列中清除的语句的进程ID(pid)。要清除语句,用户可以在Master主机上打开一个终端窗口(作为gpadmin数据库超级用户或者root)并且取消对应的进程。例如:

=# pg_cancel_backend(31905)
Note:

不要使用任何的操作系统KILL命令。

查看活动语句的优先权

gp_toolkit管理方案有一个名为gp_resq_priority_statement的视图,它列出了当前正在被执行的语句并且提供优先权、会话ID和其他信息。

T这个视图只有通过gp_toolkit管理方案才可用。更多信息请见Greenplum数据库参考指南

重置活动语句的优先权

超级用户可以使用内建函数gp_adjust_priority(session_id,statement_count,priority)调整当前正在被执行的语句的优先权。使用这个函数,超级用户可以提升或者降低任意查询的优先权。例如:

=# SELECT gp_adjust_priority(752, 24905, 'HIGH')

为了获得这个函数所需的会话ID和语句计数参数,超级用户可以使用gp_toolkit管理方案的视图gp_resq_priority_statement。从该视图用户可以把这些值用作该函数的参数。

  • rqpsession列的值用作session_id参数
  • rqpcommand列的值用作statement_count参数
  • rqppriority列的值是当前优先权。可以指定字符串值MAXHIGHMEDIUM或者LOW作为priority
Note: gp_adjust_priority()函数只影响指定的语句。同一资源队列中后续的语句还是使用该队列正常指派的优先权执行。