GP的资源队列,只针对普通用户有效,superuser不受影响
一、创建资源队列语法:
Command: CREATE RESOURCE QUEUE
Description: create a new resource queue for workload management
Syntax:
CREATE RESOURCE QUEUE name WITH (queue_attribute=value [, ... ])
where queue_attribute is:
ACTIVE_STATEMENTS=integer
[ MAX_COST=float [COST_OVERCOMMIT={TRUE|FALSE}] ]
[ MIN_COST=float ]
[ PRIORITY={MIN|LOW|MEDIUM|HIGH|MAX} ]
[ MEMORY_LIMIT='memory_units' ]
| MAX_COST=float [ COST_OVERCOMMIT={TRUE|FALSE} ]
[ ACTIVE_STATEMENTS=integer ]
[ MIN_COST=float ]
[ PRIORITY={MIN|LOW|MEDIUM|HIGH|MAX} ]
[ MEMORY_LIMIT='memory_units' ]
资源队列的设置
1 ACTIVE_STATEMENTS
&emsp#允许同时运行(active状态)的SQL数,-1不限
表示资源队列中,允许同时执行的SQL。
(注意当QUERY的成本低于min_cost时,不需要排队,直接运行。)
2 PRIORITY ={MIN LOW MEDIUM HIGH MAX}
#指当前资源队列的优先级,当资源紧张时,优先将CPU资源分配给高优先级的资源队列。
#(处于高优先级的资源队列中的SQL,可以获得更高优先级的CPU资源)。
#建议将实时性要求高的查询对应的用户分配到高优先级的资源队列中。
3 Memory_limit ‘memory_units kB,MB or GB’
#设置资源队列中所有SQL允许的最大内存使用量。-1不限
#(但是受前面提到的数据库或系统参数限制,触发OOM错误)
4 min_cost float
#(资源超限时,是需要排队的)但是,当QUERY的成本低于min_cost时,
#不需要排队,直接运行。(也就是说小查询,就让他跑吧。
5 max_cost float
#设置浮点或指数((for example 100.0),(for example 1e+2)),-1 不限制
#表示资源组允许同时执行的QUERY加起来的COST上限。
#COST是SQL执行计划中的总成本。
6、COST_OVERCOMMIT boolean,
#当系统空闲时,是否允许(TRUE)超过max_cost的限制。
1、创建一个资源策略
create resource queue myqueue with(max_cost=10000.0);
2、修改资源队列限制举例:
ALTER RESOURCE QUEUE myqueue WITH (MAX_COST=-1.0, MIN_COST= -1.0);
3、然后把这个资源策略赋权给一个用户
alter role skate resource queue myqueue .
4、如果某个资源策略已经授予给了用户,则他不能被删除。
alter role skate resource queue none。解除用户skate的资源策略。
建议的资源队列使用方法:
GPDB默认的资源队列为pg_default,如果不创建队列,那么所有的用户都会被指定给pg_default。这是非常不建议的。
建议的做法是为每个用户创建一个资源队列。(因为通常一个数据库用户对应一个业务。不同的数据库用户可能对应不同的业务或者使用者(例如业务用户、分析师用户、开发者、DBA等)。)
postgres=# select * from pg_resqueue_attributes;
rsqname | resname | ressetting | restypid
------------+-------------------+------------+----------
pg_default | active_statements | 20 | 1
pg_default | max_cost | -1 | 2
pg_default | min_cost | 0 | 3
pg_default | cost_overcommit | 0 | 4
pg_default | priority | medium | 5
pg_default | memory_limit | -1 | 6
如果每个时间段的资源需求不一样,可以写一个CRONTAB任务,定时的调整资源队列的限制。
例如白天分析师的优先级更高,晚上处理报表的队列优先级更高。
目前Greenplum还不支持按时间段来设置资源限制,所以只能外部部署任务,alter resource queue来实现。
通过gp_toolkit提供的视图,可以观察资源队列的资源使用。
- gp_toolkit.gp_resq_activity
- gp_toolkit.gp_resq_activity_by_queue
- gp_toolkit.gp_resq_priority_backend
- gp_toolkit.gp_resq_priority_statement
- gp_toolkit.gp_resq_role
- gp_toolkit.gp_resqueue_status
二、资源队列相关参数
Greenplum的内存设定,受几个因素影响,首先能够被限制内存使用的,只能是普通用户,不能是supersuer。
注意所有资源队列的内存加起来不要超过gp_vmem_protect_limit的限制。
1、gp_resqueue_memory_policy,资源队列的内存管理策略
postgres=# show gp_resqueue_memory_policy;
gp_resqueue_memory_policy
---------------------------
eager_free
=auto:内存的消耗由 statement_mem 和 资源队列的memory_limit两个参数决定,单条QUERY允许申请的内存将突破资源队列的MEMORY_LIMIT限制。
--示例:
=> SET statement_mem='2GB';
=> SELECT * FROM my_big_table WHERE column='value' ORDER BY id;
=> RESET statement_mem;
注意,还有一个系统参数max_statement_mem,这个可以理解为SEGMENT级别的内存使用安全控制阀,单个QUERY申请的memory不能超过max_statement_mem。
意思是你可以随便改会话级的statement_mem参数,但是不要随便max_statement_mem参数。
建议的max_statement_mem设置:(seghost物理内存/平均并发查询数)
(seghost_physical_memory) / (average_number_concurrent_queries)
=eager_free:表示数据库在评估SQL对内存的申请渴望时,分阶段统计,也就是说一个SQL可能总共需要申请1G内存,但是每个阶段只申请100MB,所以需要的内存实际上是100MB。
使用eager_free策略,可以降低QUERY报内存不足的可能性。
2、gp_resqueue_priority,是否使用资源队列的优先级。
ON使用,OFF不使用。不使用资源队列优先级时,所有队列公平对待。
postgres=# show gp_resqueue_priority;
gp_resqueue_priority
----------------------
on
3、gp_resqueue_priority_cpucores_per_segment,每个SEGMENT可以使用的CPU核数,
例如8核的机器,跑了2个PRIMARY SEGMENT,则配置为4。master 上面如果没有其他节点,配置为8。当发生CPU抢占时,优先级高的资源组中运行的SQL,优先分配CPU资源。
postgres=# show gp_resqueue_priority_cpucores_per_segment;
gp_resqueue_priority_cpucores_per_segment
-------------------------------------------
4
4、gp_resqueue_priority_sweeper_interval,CPU时间片统计间隔,
SQL执行时,计算它的share值(根据优先级以及计算gp_resqueue_priority_cpucores_per_segment出来)。越小越频繁,优先级设置带来的效果越好。但是overhead越大。
postgres=# show gp_resqueue_priority_sweeper_interval;
gp_resqueue_priority_sweeper_interval
---------------------------------------
1000
三、限制了资源队列但是并发执行的QUERY依旧很高,原因分析
当我们创建了资源队列,但是你发现并没有限制住并发时,可能是什么原因呢?
因为在资源队列中有一个开关,如果SQL的COST低于设置的值时,SQL依旧被放行,实际上就是简单的小SQL,不会和大SQL一样排队。
就好像银行的窗口,取钱业务通常可以很快办理,但是开卡的业务需要很久。那么在排队时,我们可以让取钱的业务不排队,直接去窗口办理。
但是,这里也可能存在问题,你怎么就知道他一定是来取钱的呢?万一他也来办卡呢?
在数据库中,有COST来标识,但是记住,他需要依赖准确的统计信息,否则可能COST不准确,例如一张1亿的表,我们没有收集统计信息的话,记录数就是0,那么对这个表的查询操作COST算出来就会很低。这样的话,大SQL也被混入执行中。
所以,此时请关注,你的统计信息是否准确。
《Oracle 自动收集统计信息机制》:https://www.modb.pro/db/403670
《Oracle_索引重建—优化索引碎片》:https://www.modb.pro/db/399543
《DBA_TAB_MODIFICATIONS表的刷新策略测试》https://www.modb.pro/db/414692
欢迎点赞支持&或留言指正错误




