GP的资源队列,只针对普通用户有效,superuser不受影响。
资源队列的设置有4个维度:
1 ACTIVE_STATEMENTS
2 PRIORITY
3 Memory_limit
4 min_cost、max_cost
创建一个资源策略
create resource queue adhoc1 with(max_cost=10000.0);
然后把这个资源策略赋权给一个用户
alter role skate resource queue adhoc1.
如果某个资源策略已经授予给了用户,则他不能被删除。
alter role skate resource queue none。解除用户skate的资源策略。
Greenplum的内存设定,受几个因素影响,首先能够被限制内存使用的,只能是普通用户,不能是supersuer。
所有设置均可以使用gpconfig工具在bin目录下执行。
参数:gp_vmem_protect_limit
默认8G,GP系统申请的虚拟内存大小,如果在查询过程中实际使用的内存大于这个值,系统会报内存溢出错误。
参数:gp_resqueue_memory_policy
此参数有两个选项:eager_free 和 auto,分别代表内存使用的两种方式,不同的选择代表不同的约束条件,后面会详细介绍。
参数:statement_mem
默认125MB,SQL查询请求是使用的内存大小。
参数:max_statement_mem
默认2000MB,限定statement_mem的最大值。
内存使用配置方式:资源队列配置参考
GP的内存配置有两种方式,由参数gp_resqueue_memory_policy的两个选项(eager_free、auto)决定。
1 eager_free
此时内存的消耗由 max_statement_mem 和 资源队列的memory_limit两个参数决定。
如果当前用户不是普通用户或没有设置资源队列的memory_limit,那么内存的消耗只受max_statement_mem这个数值限定,该数值默认为2000mb。
2 auto
此时内存的消耗由 statement_mem 和 资源队列的memory_limit两个参数决定。
同样资源队列的memory_limit只对普通用户有效,而statement_mem默认值为125mb。
配置案例:案例均为不限制资源队列的memory_limit
1 eager_free的情况
既然不限制memory_limit,则max_statement_mem的默认值为2000M,那么如果查询一个查询的内存消耗不高于2000M,则可以正常使用,反之会提示内存不足。
假设一个SQL消耗1G内存(不超过max),同时并发10个查询,则需要向系统申请月10G内存,大于了gp_vmem_protect_limit默认的8G虚拟内存。
此时如果 实际用到的内存×节点上的实例总数 >> 节点内存,就好出现内存溢出的错误。
2 auto的情况
同样没有设置memory_limit,而statement_limit为125M限制,需要向操作系统申请 125M × 10个查询,约1.25G。
综上情况,场景1 中每个实例需要10G内存,gp_vmem_protect_limit的默认值是8G,每个实例向操作系统申请8G,其余不够的2G通过 pgsql_tmp目录响应。
场景2中每个实例同样需要10G内存,但由于memory_limit125M的限制,10条语句申请1.25G内存,其余则由pgsql_tmp目录响应。
验证测试方法和场景如下:
1 集群节点信息
2 参数配置
gp_vmem_protect_limit 8192
max_statement_mem 2000MB
用户u1,资源队列:active_statements=10,Memory_limit='150MB'
statement_mem 125MB
3
10G数据量的TPCH,执行查询
select s_name,count(*) as numwait from supplier,lineitem l1,orders,nation where s_suppkey = l1.l_suppkey and o_orderkey = l1.l_orderkey and o_orderstatus = 'F' and l1.l_receiptdate > l1.l_commitdate and exists ( select * from lineitem l2 where l2.l_orderkey = l1.l_orderkey and l2.l_suppkey <> l1.l_suppkey) and not exists (select * from lineitem l3 where l3.l_orderkey = l1.l_orderkey and l3.l_suppkey <> l1.l_suppkey and l3.l_receiptdate > l3.l_commitdate ) and s_nationkey = n_nationkey and n_name ='UNITED KINGDOM' group by s_name order by numwait desc,s_name LIMIT 100;
4
u1登录,10个并发执行查询:
eager_free模式,有资源队列,因此memory_limit(150MB)和max_statement_mem(2000MB)生效,完成查询耗时约 1033695毫秒
auto模式,有资源队列,memory_limit(150M)和statement_mem(125MB)生效,耗时约 999356毫秒。
auto模式比eager_free模式快30秒左右。
其他过多的场景由于资源限制,没有做过多的尝试,整体来说auto的形式比eager_free好。不过这个TPCH的查询,如果不用资源队列加以限制,使用管理员登录,直接查询失败oom.
另外需要注意的是:
1 资源队列的memory_limit不能设置小于150MB,否则执行查询时会提示 ERROR: deadlock detected, locking against self
2 max_statement_mem 不能大于2000MB,否则数据库启动会失败。
3 statement_mem不能大于max_statement_mem,否则数据库启动会失败。