Greenplum中内存设置不合理导致的报错

拟墨画扇 提交于 2020-02-28 18:40:31

声明:文中观点为作者的个人观点、不代表官方、如需更多帮助,请联系Pivotal官方·转载必须注明出处

 

针对Greenplum中主要的内存设置参数做如下说明(不涉及OS级别参数):

statement_mem:

ERROR: insufficient memory reserved for statement (memquota.c:228)

当扫描一张分区特别多的表时,会出现该错误,此时需要将默认的125MB的配置提高,建议在500MB左右或者更高一些。

不过,如果需要做系统级别的修改需要谨慎对待,后面会结合几个参数说明。

gp_vmem_protect_limit:

"ERROR","53200","Out of memory.Failed on request of size 156 bytes.(context 'CacheMemoryContext') (aset.c:840)"

"ERROR","53400","Out of memory (seg13 slice13 sdw1-1:40001 pid=10183)","VM Protect failed to allocate 8388608 bytes, 6 MB available"

该错误是Greenplum系统无法从OS申请到所需要的内存导致的错误,因为gp_vmem_protect_limit配置高于OS所能提供的能力,当Greenplum

申请超过OS能力时,会得到该异常信息。解决办法是确保内存消耗不超过gp_vmem_protect_limit配置,官方建议不超过其90%。

针对最常见的内存错误OOM,需要说明(针对4.1之后版本,早起版本请前去查询相关文档):


单语句的内存消耗受3个参数控制:gp_resqueue_memory_policy、statement_mem、max_statement_mem

    A、缺省gp_resqueue_memory_policy配置为eager_free,在此情况下,内存将物尽其用(我从词面理解的,官方并未给出详细说明),但

       不能超过max_statement_mem的限制以及resource queue的memory_limit限制,此时如果resource queue未做限制(缺省资源队列

       均无内存限制),既存在OOM缺口,而此时statement_mem将不具备严格限制功能,同时max_statement_mem的缺省值为2000MB。

    B、当gp_resqueue_memory_policy配置为auto时,内存消耗将受statement_mem和resource queue的memory_limit限制,同样,

       缺省资源队列无内存限制,不过,statement_mem的缺省值为125MB。

综合考虑内存限制参数,由于资源队列的memory_limit缺省是没有限制的,我们假设有10个需要消耗1000MB的语句同时提交。

       对于A情况来说,需要向OS申请1000MB×10≈10GB的内存,这已经大于gp_vmem_protect_limit的缺省限制,此时,如果

   gp_vmem_protect_limit×节点节点实例数>>节点内存,则极有可能出现OOM错误,此时通过放大gp_vmem_protect_limit是可能带来

   缓解的,但并非良措,因为超过物理内存部分的内存申请需要SWAP来响应。而且,很容易超过物理内存+SWAP的总和,将继续出现OOM且

    将进入无解状态。

       对于B情况来说,需要向OS申请125MB×10≈1.25GB<<10GB的内存,通常的硬件环境,每个Instance不至于少于2GB的内存。

       如果按照gp_vmem_protect_limit缺省为8192来计算,对于A情况,每个Instance需要向系统申请8GB内存,其余的2GB需要pgsql_tmp

   目录来响应。而对于B情况,每个Instance需要向系统申请2GB的内存,其余的8GB需要pgsql_tmp目录来响应。由于pgsql_tmp位于性能高于

   SWAP的数据盘(通常的环境是如此,不排除高福帅配置),性能有一定保障,B情况通常不会出现OOM,且可承受的并发数远大于A情况。

    以上比较详细的说明了GP内存控制的几个关键参数,若要避免OOM,最好还是综合考虑,GP从4.1版本之后设置缺省的A情况也有其合理性,因为,

如果按照B情况设置,多数情况下内存不能物尽其用,且需要性能较低的pgsql_tmp来承担内存的角色,实在不划算。可以尝试设置资源队列的

memory_limit参数,但此方式也有一些小问题,比如超限SQL或被自动cancel掉等等。最好的办法还是充分优化那些低劣的高内存消耗的SQL,合理

安排高内存消耗SQL的并发度。数据库的智能程度是有限的。因为Greenplum定位在数据仓库上,对任何SQL都会尽量调动所有可调动的资源去完成

计算,其资源控制上必然不能做到完美,关键还是深入的去理解数据库工作机制,让驴拉磨,牛犁地,物尽人用。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!