aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-06-18 20:12:47 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-06-18 20:12:51 -0400
commitdf8b7bc9ffff5b00aacff774600b569992cddeb8 (patch)
treed9136c85540b121ff5d229320cc761d336f95107 /src
parent960661980beb50c5d21e4b2855ae109e9a130326 (diff)
downloadpostgresql-df8b7bc9ffff5b00aacff774600b569992cddeb8.tar.gz
postgresql-df8b7bc9ffff5b00aacff774600b569992cddeb8.zip
Improve our mechanism for controlling the Linux out-of-memory killer.
Arrange for postmaster child processes to respond to two environment variables, PG_OOM_ADJUST_FILE and PG_OOM_ADJUST_VALUE, to determine whether they reset their OOM score adjustments and if so to what. This is superior to the previous design involving #ifdef's in several ways. The behavior is now available in a default build, and both ends of the adjustment --- the original adjustment of the postmaster's level and the subsequent readjustment by child processes --- can now be controlled in one place, namely the postmaster launch script. So it's no longer necessary for the launch script to act on faith that the server was compiled with the appropriate options. In addition, if someone wants to use an OOM score other than zero for the child processes, that doesn't take a recompile anymore; and we no longer have to cater separately to the two different historical kernel APIs for this adjustment. Gurjeet Singh, somewhat revised by me
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/fork_process.c57
1 files changed, 18 insertions, 39 deletions
diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c
index f6df2de8706..5e5bd35e7e3 100644
--- a/src/backend/postmaster/fork_process.c
+++ b/src/backend/postmaster/fork_process.c
@@ -31,6 +31,7 @@ pid_t
fork_process(void)
{
pid_t result;
+ const char *oomfilename;
#ifdef LINUX_PROFILE
struct itimerval prof_itimer;
@@ -71,62 +72,40 @@ fork_process(void)
* 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_score_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_SCORE_ADJ #defined to 0, or to some other value that you
- * want child processes to adopt here.
+ * setting its OOM score adjustment negative (which has to be done in
+ * a root-owned startup script). Since the adjustment is inherited by
+ * child processes, this would ordinarily mean that all the
+ * postmaster's children are equally protected against OOM kill, which
+ * is not such a good idea. So we provide this code to allow the
+ * children to change their OOM score adjustments again. Both the
+ * file name to write to and the value to write are controlled by
+ * environment variables, which can be set by the same startup script
+ * that did the original adjustment.
*/
-#ifdef LINUX_OOM_SCORE_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_score_adj", O_WRONLY, 0);
-
- /* We ignore all errors */
- if (fd >= 0)
- {
- char buf[16];
- int rc;
+ oomfilename = getenv("PG_OOM_ADJUST_FILE");
- snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_SCORE_ADJ);
- rc = write(fd, buf, strlen(buf));
- (void) rc;
- close(fd);
- }
- }
-#endif /* LINUX_OOM_SCORE_ADJ */
-
- /*
- * Older Linux kernels have oom_adj not oom_score_adj. This works
- * similarly except with a different scale of adjustment values. If
- * it's necessary to build Postgres to work with either API, you can
- * define both LINUX_OOM_SCORE_ADJ and LINUX_OOM_ADJ.
- */
-#ifdef LINUX_OOM_ADJ
+ if (oomfilename != NULL)
{
/*
* 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);
+ int fd = open(oomfilename, O_WRONLY, 0);
/* We ignore all errors */
if (fd >= 0)
{
- char buf[16];
+ const char *oomvalue = getenv("PG_OOM_ADJUST_VALUE");
int rc;
- snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_ADJ);
- rc = write(fd, buf, strlen(buf));
+ if (oomvalue == NULL) /* supply a useful default */
+ oomvalue = "0";
+
+ rc = write(fd, oomvalue, strlen(oomvalue));
(void) rc;
close(fd);
}
}
-#endif /* LINUX_OOM_ADJ */
/*
* Make sure processes do not share OpenSSL randomness state.