aboutsummaryrefslogtreecommitdiff
path: root/src/backend/postmaster/fork_process.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-01-11 18:39:32 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-01-11 18:39:32 +0000
commitd5e0029862be8729f2cb25736469ed71068424c5 (patch)
treed464e7360405e945cbd1f47d6e48d6f0d4199eb3 /src/backend/postmaster/fork_process.c
parent292176a118da6979e5d368a4baf27f26896c99a5 (diff)
downloadpostgresql-d5e0029862be8729f2cb25736469ed71068424c5.tar.gz
postgresql-d5e0029862be8729f2cb25736469ed71068424c5.zip
Add some simple support and documentation for using process-specific oom_adj
settings to prevent the postmaster from being OOM-killed on Linux systems. Alex Hunsaker and Tom Lane
Diffstat (limited to 'src/backend/postmaster/fork_process.c')
-rw-r--r--src/backend/postmaster/fork_process.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c
index fea72d7e54c..91ef9de0214 100644
--- a/src/backend/postmaster/fork_process.c
+++ b/src/backend/postmaster/fork_process.c
@@ -7,12 +7,14 @@
* Copyright (c) 1996-2010, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/fork_process.c,v 1.10 2010/01/02 16:57:50 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/fork_process.c,v 1.11 2010/01/11 18:39:32 tgl Exp $
*/
#include "postgres.h"
#include "postmaster/fork_process.h"
+#include <fcntl.h>
#include <time.h>
+#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
@@ -60,6 +62,38 @@ fork_process(void)
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;