Greenplum集群 申请内存失败 Out of memory

一、问题简介

DETAIL: VM protect failed to allocate 65592 bytes from system, VM Protect 8039 MB available

    小白今天在往Greenplum集群导入数据的时候,报了如上错误,简单来说大概是,VM认为可用内存还有8039MB,但是向操作系统申请65592bytes的内存却失败了!

    在确认了服务器的内存和磁盘空间都是足够的情况下,便查阅了一些网上的资料,下面是我个人认为有用并且尝试过的一些方法,分享给大家。

二、方法尝试

1、修改数据库参数配置 gp_max_plan_size 

gpconfig -c gp_max_plan_size -v "200MB"

    Linux命令行输入以上指令,然后重启集群生效。

    小白尝试了200MB、100MB、50MB,均未能解决问题。

2、修改数据库参数配置 gp_vmem_protect_limit

gpconfig -c gp_vmem_protect_limit -v "4096"

    Linux命令行输入以上指令,注意此处没有“MB”,然后重启集群生效。

    小白尝试了4096MB、2048MB、1024MB、512MB,均未能解决问题。

3、修改Linux系统的内存分配策略 vm.overcommit_memory

sysctl vm.overcommit_memory=1 或 sysctl  -w  vm.overcommit_memory=1   
临时的,重启Linux系统后会恢复原样

echo 1 > /proc/sys/vm/overcommit_memory     
临时的,重启linux系统后会恢复原样

编辑 vi /etc/sysctl.conf ,修改vm.overcommit_memory=1,然后 sysctl -p 使配置生效   
永久的,重启Linux系统仍然有效

    Linux命令行输入以上指令,进行设置

    Linux命令行输入 cat /proc/sys/vm/overcommit_memory 可查看参数值

    小白的集群中此参数为2,所以试着将参数值设置成0和1,让系统在分配内存的时候更加“严谨”,进而避免了后续因内存不足而被迫杀死一些进程,至此问题终解决。

三、解释

内存分配策略参数overcommit_memory

这是内存分配策略,可选值:0、1、2。

0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存        申请失败,并把错误返回给应用进程。
1: 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2: 表示内核允许分配超过所有物理内存和交换空间总和的内存

参数设置是一种取舍,均衡存在于万物之间

什么是Overcommit和OOM

        Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做 Overcommit。当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。

        当OOM killer发生时,Linux会选择杀死一些进程,选择进程的函数是oom_badness函数(在mm/oom_kill.c中)。该函数会计算每个进程的点数(0~1000),点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且 oom_score_adj可以被设置(-1000最低,1000最高)。

以下是一些可能会用到的Greenplum集群指令:

gpstop                    关闭集群

gpstart                    启动集群

gpstate                   查看集群状态

最后,数据导入时Greenplum已经不报OOM异常了,但是疑团并未解开。即使vm.overcommit_memory=2,但是系统可用内存在数据库进程运行前后,看上去都是充足的,为何会发生OOM呢?
欢迎大家指点和分享!



你可能感兴趣的:(Greenplum集群 申请内存失败 Out of memory)