postgres 大表merge join的时候占用了大量的work_mem导致进程被杀。
参考网上程序写了如下程序进行测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PAGE_SZ (1<<12)
int gb=3;
int main(){
int i=0;
for(i=0;i<((unsigned long)gb<<30)/PAGE_SZ;i++){
void *m=malloc(PAGE_SZ);
if(!m) break;
memset(m,0,1);
}
printf("%d KB",i*4);
getchar();
return 0;
}
我的测试环境为内存4G,swap4G
程序执行后每次会申请PAGE_SZ内存,直到 (gb<<30) 内存
测试结果如下
当执行程序c333时候,d333时候。总体虚拟内存占用6G多,由于部分内存可以swap进入硬盘,程序并未崩溃
再次执行的一个程序时候会导致最先运行的程序被oom机制 kill掉。
例如下图中运行3个时候,进行到一定时候,最先运行的程序会被kill
当执行运行单个程序申请20G内存的时候一样会被kill掉,如下图。
当对a20G 这个程序进行保护。执行如下命令。
pgrep -f "a20G" | while read PID; do echo -17 > /proc/$PID/oom_adj;done
-17为OOM机制对此进程失效。结果后果很严重如下图
我所有连接上的ssh都被中断,想必原因是kill不了a20G这个程序,只能把其他的能杀的都杀了吧。
最后急急忙忙去机房重启机器,查看内核日志,好像未有什么明显错误。
ssh中断后我已经无法知道还会继续发生何事。
但是我可以接上显示器去机房看的。不过为时已晚,我第一件想到的就是重启机器了。
不过大胆猜想估计也就是机器卡那边,不会有什么大的异常发生吧。