在 Redis 文档中明确指出vm.overcommit_memory
应设置为1
以确保后台保存较新的失败:http://redis.io/topics/faq
然而
在 postgresql 文档中说,应该vm.overcommit_memory
设置为2
避免 post master 进程不被 oom killer 杀死:http://www.postgresql.org/docs/9.3/static/kernel-resources.html
现在,这当然是矛盾的。我该怎么办?
我的 redis db 限制为 20GB。服务器有 252GB 物理 RAM。Postgresql 很少使用超过 100GB 的物理 RAM。
PS:我使用的是 ubuntu 14、Redis 3.0 和 Postgresql 9.3
答案1
您可以采用 Redis 的建议,因为 Ubuntu 的 PostgreSQL 软件包已经实现了文档中提到的方法,以防止不明智的 OOM 终止 postmaster 进程。
它就在文档中你引用的部分之后。摘自Linux 内存过量使用
另一种方法(无论是否更改 vm.overcommit_memory 都可以使用)是将 postmaster 进程的特定进程 oom_score_adj 值设置为 -1000,从而保证它不会被 OOM killer 锁定。最简单的方法是执行
echo -1000 > /proc/self/oom_score_adj
在调用 postmaster 之前,在 postmaster 的启动脚本中。请注意,此操作必须以 root 身份执行,否则将不起作用;因此,root 拥有的启动脚本是执行此操作的最简单位置。如果执行此操作,您可能还希望构建 PostgreSQL,并将 -DLINUX_OOM_SCORE_ADJ=0 添加到 CPPFLAGS。这将导致 postmaster 子进程以正常的 oom_score_adj 值零运行,以便 OOM 杀手仍可以在需要时针对它们。
在 Ubuntu 14 上,pg_ctlcluster
启动 postgres 实例的脚本如下:
# have the postmaster start with increased OOM killer protection; 9.1 and
# later has builtin support for resetting the adjustment of child processes
if ($action eq 'start' && $version >= '9.1') {
if (-w '/proc/self/oom_score_adj') {
open F, '>/proc/self/oom_score_adj';
print F "-900\n";
close F;
}
}
因此它-900
为邮局局长的 OOM 分数分配了一个固定值,
并/usr/lib/postgresql/9.3/bin/pg_config pg_config --cflags
说:
-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -fPIC -pie -I/usr/include/mit-krb5-DLINUX_OOM_SCORE_ADJ=0-fno-omit-frame-pointer -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g
postmaster
因此, OOM 终止程序永远不应该选择它,但子后端进程(每个连接一个)可以。