现象:
以下2个案例:
1.RPSM_TRADE_INFO_NLC这个脚本的 560行报错
脚本中写法:
DELETEFROM $RPSM_SCH.RPSM_TRADE_INFO O
USING
TEMP_RPSM_TRADE_INFO_NLC_YXLC_PRE N
WHEREN.TRANS_SID = O.TRANS_SID
ANDO.SRC_SYS_CD = 'NLC-XT';
后来修改为:
使用 DELETE FROM $RPSM_SCH.RPSM_TRADE_INFO WHERE TRANS_SID IN (SELECT TRANS_SID FROMTEMP_RPSM_TRADE_INFO_NLC_YXLC_PRE)
也是执行不通过
再后来把此脚本拆分为2个脚本执行,其中涉及到使用DELETE删除RPSM_TRADE_INFO表中数据时一样会报错(RPSM_TRADE_INFO该表每天增量流水,删除历史数据原因是:历史流水中的产品到期日不对,需要用最新的更新)
2.RPSM_TRADE_INFO_BX
执行到这个脚本的309--367行报错,一共5个表关联,并不复杂,但是一直执行不过去
最近出现报错比较多的就是访问同一个表的多个分区,但是又无法避免需要访问多个分区
相关文章:
针对Greenplum中主要的内存设置参数做如下说明(不涉及OS级别参数):
statement_mem:
ERROR: insufficient memory reserved forstatement (memquota.c:228)
当扫描一张分区特别多的表时,会出现该错误,此时需要将默认的125MB的配置提高,建议在500MB左右或者更高一些。
不过,如果需要做系统级别的修改需要谨慎对待,后面会结合几个参数说明。
gp_vmem_protect_limit:
"ERROR","53200","Outof memory.Failed on request of size 156bytes.(context 'CacheMemoryContext') (aset.c:840)"
"ERROR","53400","Outof memory (seg13 slice13 sdw1-1:40001 pid=10183)","VM Protectfailed 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和resourcequeue的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都会尽量调动所有可调动的资源去完成
计算,其资源控制上必然不能做到完美,关键还是深入的去理解数据库工作机制,让驴拉磨,牛犁地,物尽人用。