Back-ported patch from Postgres devel head: reset oom_adj to zero in any postmaster child process. This allows us to disable OOM kill on the postmaster (see the init script) without affecting OOM behavior for child processes. diff -Naur postgresql-8.4.2.orig/src/backend/postmaster/fork_process.c postgresql-8.4.2/src/backend/postmaster/fork_process.c --- postgresql-8.4.2.orig/src/backend/postmaster/fork_process.c 2009-01-01 12:23:46.000000000 -0500 +++ postgresql-8.4.2/src/backend/postmaster/fork_process.c 2010-01-11 12:28:17.000000000 -0500 @@ -12,7 +12,9 @@ #include "postgres.h" #include "postmaster/fork_process.h" +#include #include +#include #include #include @@ -60,6 +62,38 @@ setitimer(ITIMER_PROF, &prof_itimer, NULL); #endif + /* + * By default, Linux tends to kill the postmaster in out-of-memory + * situations, because it blames the postmaster for the sum of child + * process sizes *including shared memory*. (This is unbelievably + * stupid, but the kernel hackers seem uninterested in improving it.) + * Therefore it's often a good idea to protect the postmaster by + * setting its oom_adj value negative (which has to be done in a + * root-owned startup script). If you just do that much, all child + * processes will also be protected against OOM kill, which might not + * be desirable. You can then choose to build with LINUX_OOM_ADJ + * #defined to 0, or some other value that you want child processes + * to adopt here. + */ +#ifdef LINUX_OOM_ADJ + { + /* + * Use open() not stdio, to ensure we control the open flags. + * Some Linux security environments reject anything but O_WRONLY. + */ + int fd = open("/proc/self/oom_adj", O_WRONLY, 0); + + /* We ignore all errors */ + if (fd >= 0) + { + char buf[16]; + + snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_ADJ); + (void) write(fd, buf, strlen(buf)); + close(fd); + } + } +#endif /* LINUX_OOM_ADJ */ } return result;