statement_mem
:
ERROR: insufficient memory reserved for statement (memquota.c:228)
不过,如果需要做系统级别的修改需要谨慎对待。
gp_vmem_protect_limit :
"ERROR","53200","Out of memory.Failed on request of size 156 bytes.(context
'CacheMemoryContext') (aset.c:840)"
该错误是Greenplum系统无法从OS申请到所需要的内存导致的错误,因为 gp_vmem_protect_limit配置高于OS所能提供的能力。
"ERROR","53400","Out of memory (seg13 slice13 sdw1-1:40001 pid=10183)","VM Protect failed to allocate 8388608 bytes, 6 MB available"
该错误是Greenplum系统已经分配的内存超过了 gp_vmem_protect_limit设置的90%阈值。
针对最常见的内存不足的报错,最有效的解决办法是降低消耗内存量大的语句的并发数 。
下面讲单语句的内存消耗相关的几个参数:
gp_resqueue_memory_policy
、
statement_mem
、
max_statement_mem
关于 gp_resqueue_memory_policy参数解释如下(其实我也没读过源码,可能理解有误):
A、缺省
gp_resqueue_memory_policy
配置为
eager_free
,在此情况下,内存将物尽其用,如前面提到,内存是按照执行计划的Slice个数进行均分的,在该模式下,当前面的Slice执行结束之后,将会尽可能的回收其不再使用的内存,以分配给后续的Slice使用,但总的内存使用量仍受到statement_mem
及resource queue的
memory_limit
限制
。不过对于使用Orca的情况下,有时候对于分区表可能会突破statement_mem的限制。
B、当
gp_resqueue_memory_policy
配置为auto时,
内存消耗将受
statement_mem
和resource queue的memory_limit限制,同样,缺省资源队列无内存限制。
综合考虑内存限制参数,假如使用缺省资源队列,memory_limit没有限制,我们假设有10个需要消耗1000MB的语句同时提交。不管是对于eager_free还是auto,10个语句需要向GP系统申请1000MB×10≈10GB的内存,这已经大于gp_vmem_protect_limit的限制,此时有可能会出现[
VM Protect failed to allocate]类型的报错,但也极大可能是不会出现的,因为语句可能不会真正的消耗1000MB内存,因为内存是按照Slice分配的,不同的Slice真正消耗的内存多数情况下小于预分配的值,比如Scan操作并不会消耗很多内存
。
总结,对于数据量大的复杂SQL,要避免出现workfile溢出情况,可以大幅度提升 max_statement_mem和statement_mem 参数以提升内存使用量。但对于出现内存不足的报错,如果有OOM,说明 gp_vmem_protect_limit设置过大,要将单机上所有Primary控制在物理内存的90%。如果是出现 [ VM Protect failed to allocate ] 类型的报错,就注意控制大任务的并发或者加配内存或者扩展机器数量。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/11022757/viewspace-720343/ ,如需转载,请注明出处,否则将追究法律责任。