On Fri, Jan 8, 2010 at 07:27, Tom Lane <t...@sss.pgh.pa.us> wrote:
> Then, somebody who wants the feature would build with, say,
>        -DLINUX_OOM_ADJ=0
> or another value if they want that.

Here is a stab at that.

It sets oom_adj for:
 autovacuum workers
 archivers (pgarch.c)
 regular backends

Also it updates the contrib linux starup script to start under an oom_adj of -17

Comments?

*** a/contrib/start-scripts/linux
--- b/contrib/start-scripts/linux
***************
*** 53,58 **** DAEMON="$prefix/bin/postmaster"
--- 53,63 ----
  # What to use to shut down the postmaster
  PGCTL="$prefix/bin/pg_ctl"

+ # Adjust oom_adj on linux to avoid the postmaster from be killed
+ # note you probably want to compile postgres with -DLINUX_OOM_ADJ=0
+ # so that regular backends will be killed on oom
+ OOM_ADJ=-17
+
  set -e

  # Only start if we can find the postmaster.
***************
*** 62,67 **** test -x $DAEMON || exit 0
--- 67,73 ----
  case $1 in
    start)
    echo -n "Starting PostgreSQL: "
+   echo $OOM_ADJ > /proc/self/oom_adj
    su - $PGUSER -c "$DAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
    echo "ok"
    ;;
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
***************
*** 1403,1408 **** StartAutoVacWorker(void)
--- 1403,1411 ----
            /* Lose the postmaster's on-exit routines */
            on_exit_reset();

+           /* allow us to be killed on oom */
+           oom_adjust();
+
            AutoVacWorkerMain(0, NULL);
            break;
  #endif
*** a/src/backend/postmaster/fork_process.c
--- b/src/backend/postmaster/fork_process.c
***************
*** 66,68 **** fork_process(void)
--- 66,97 ----
  }

  #endif   /* ! WIN32 */
+
+ #if defined(__linux__) && defined(LINUX_OOM_ADJ)
+ /*
+  * By default linux really likes to kill the postmaster on oom.
+  * Because linux does not take SYSV shared mem into account it
+  * (almost) always will SIGKILL the postmaster on an oom event.
+  *
+  * In the event you started the postmaster under a low (negative)
+  * oom_adj.  This will adjust regular backends, autovac and archivers
+  * to LINUX_OOM_ADJ on fork().  Allowing them to be killed in an oom
+  * event.
+  *
+  * Later we might add other OS oom type stuff here.
+  */
+ void
+ oom_adjust(void)
+ {
+   FILE *oom = fopen("/proc/self/oom_adj", "w");
+
+   /* ignore errors we dont really care */
+   if (oom)
+   {
+       fprintf(oom, "%d\n", LINUX_OOM_ADJ);
+       fclose(oom);
+   }
+ }
+ #else
+ void oom_adjust(void) { }
+ #endif
*** a/src/backend/postmaster/pgarch.c
--- b/src/backend/postmaster/pgarch.c
***************
*** 170,175 **** pgarch_start(void)
--- 170,178 ----
            /* Drop our connection to postmaster's shared memory, as well */
            PGSharedMemoryDetach();

+           /* allow us to be killed on oom */
+           oom_adjust();
+
            PgArchiverMain(0, NULL);
            break;
  #endif
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
***************
*** 3076,3081 **** BackendStartup(Port *port)
--- 3076,3084 ----
        /* Perform additional initialization and collect startup packet */
        BackendInitialize(port);

+       /* allow us to be killed on oom */
+       oom_adjust();
+
        /* And run the backend */
        proc_exit(BackendRun(port));
    }
*** a/src/include/postmaster/fork_process.h
--- b/src/include/postmaster/fork_process.h
***************
*** 13,17 ****
--- 13,18 ----
  #define FORK_PROCESS_H

  extern pid_t fork_process(void);
+ extern void oom_adjust(void);

  #endif   /* FORK_PROCESS_H */
*** a/contrib/start-scripts/linux
--- b/contrib/start-scripts/linux
***************
*** 53,58 **** DAEMON="$prefix/bin/postmaster"
--- 53,63 ----
  # What to use to shut down the postmaster
  PGCTL="$prefix/bin/pg_ctl"
  
+ # Adjust oom_adj on linux to avoid the postmaster from be killed
+ # note you probably want to compile postgres with -DLINUX_OOM_ADJ=0
+ # so that regular backends will be killed on oom
+ OOM_ADJ=-17
+ 
  set -e
  
  # Only start if we can find the postmaster.
***************
*** 62,67 **** test -x $DAEMON || exit 0
--- 67,73 ----
  case $1 in
    start)
  	echo -n "Starting PostgreSQL: "
+ 	echo $OOM_ADJ > /proc/self/oom_adj
  	su - $PGUSER -c "$DAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
  	echo "ok"
  	;;
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
***************
*** 1403,1408 **** StartAutoVacWorker(void)
--- 1403,1411 ----
  			/* Lose the postmaster's on-exit routines */
  			on_exit_reset();
  
+ 			/* allow us to be killed on oom */
+ 			oom_adjust();
+ 
  			AutoVacWorkerMain(0, NULL);
  			break;
  #endif
*** a/src/backend/postmaster/fork_process.c
--- b/src/backend/postmaster/fork_process.c
***************
*** 66,68 **** fork_process(void)
--- 66,97 ----
  }
  
  #endif   /* ! WIN32 */
+ 
+ #if defined(__linux__) && defined(LINUX_OOM_ADJ)
+ /*
+  * By default linux really likes to kill the postmaster on oom.
+  * Because linux does not take SYSV shared mem into account it
+  * (almost) always will SIGKILL the postmaster on an oom event.
+  *
+  * In the event you started the postmaster under a low (negative)
+  * oom_adj.  This will adjust regular backends, autovac and archivers
+  * to LINUX_OOM_ADJ on fork().  Allowing them to be killed in an oom
+  * event.
+  *
+  * Later we might add other OS oom type stuff here.
+  */
+ void
+ oom_adjust(void)
+ {
+ 	FILE *oom = fopen("/proc/self/oom_adj", "w");
+ 
+ 	/* ignore errors we dont really care */
+ 	if (oom)
+ 	{
+ 		fprintf(oom, "%d\n", LINUX_OOM_ADJ);
+ 		fclose(oom);
+ 	}
+ }
+ #else
+ void oom_adjust(void) { }
+ #endif
*** a/src/backend/postmaster/pgarch.c
--- b/src/backend/postmaster/pgarch.c
***************
*** 170,175 **** pgarch_start(void)
--- 170,178 ----
  			/* Drop our connection to postmaster's shared memory, as well */
  			PGSharedMemoryDetach();
  
+ 			/* allow us to be killed on oom */
+ 			oom_adjust();
+ 
  			PgArchiverMain(0, NULL);
  			break;
  #endif
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
***************
*** 3076,3081 **** BackendStartup(Port *port)
--- 3076,3084 ----
  		/* Perform additional initialization and collect startup packet */
  		BackendInitialize(port);
  
+ 		/* allow us to be killed on oom */
+ 		oom_adjust();
+ 
  		/* And run the backend */
  		proc_exit(BackendRun(port));
  	}
*** a/src/include/postmaster/fork_process.h
--- b/src/include/postmaster/fork_process.h
***************
*** 13,17 ****
--- 13,18 ----
  #define FORK_PROCESS_H
  
  extern pid_t fork_process(void);
+ extern void oom_adjust(void);
  
  #endif   /* FORK_PROCESS_H */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to