]> granicus.if.org Git - postgresql/commitdiff
When a background worker exists with code 0, unregister it.
authorRobert Haas <rhaas@postgresql.org>
Wed, 7 May 2014 21:43:39 +0000 (17:43 -0400)
committerRobert Haas <rhaas@postgresql.org>
Wed, 7 May 2014 21:44:42 +0000 (17:44 -0400)
The previous behavior was to restart immediately, which was generally
viewed as less useful.

Petr Jelinek, with some adjustments by me.

doc/src/sgml/bgworker.sgml
src/backend/postmaster/bgworker.c
src/backend/postmaster/postmaster.c
src/include/postmaster/bgworker.h

index fd32d6cb0c9236210b086a826acb777af8bafa16..d3c8ddb382fbb2ee3f27b0f718dfb25ae6726f69 100644 (file)
@@ -166,10 +166,16 @@ typedef struct BackgroundWorker
   </para>
 
   <para>
-   Background workers are expected to be continuously running; if they exit
-   cleanly, <command>postgres</> will restart them immediately.  Consider doing
-   interruptible sleep when they have nothing to do; this can be achieved by
-   calling <function>WaitLatch()</function>.  Make sure the
+   If <structfield>bgw_restart_time</structfield> for a background worker is
+   configured as <literal>BGW_NEVER_RESTART</>, or if it exits with an exit
+   code of 0 or is terminated by <function>TerminateBackgroundWorker</>,
+   it will be automatically unregistered by the postmaster on exit.
+   Otherwise, it will be restarted after the time period configured via
+   <structfield>bgw_restart_time</>, or immediately if the postmaster
+   reinitializes the cluster due to a backend failure.  Backends which need
+   to suspend execution only temporarily should use an interruptible sleep
+   rather than exiting; this can be achieved by calling
+   <function>WaitLatch()</function>. Make sure the
    <literal>WL_POSTMASTER_DEATH</> flag is set when calling that function, and
    verify the return code for a prompt exit in the emergency case that
    <command>postgres</> itself has terminated.
index 64c97229931912383d70b24f0d2597fa039f3166..85a3b3a077340c2f6d3144b762cc625ba3edb298 100644 (file)
@@ -884,8 +884,8 @@ RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
  * running but is no longer.
  *
  * In the latter case, the worker may be stopped temporarily (if it is
- * configured for automatic restart, or if it exited with code 0) or gone
- * for good (if it is configured not to restart and exited with code 1).
+ * configured for automatic restart and exited non-zero) or gone for
+ * good (if it exited with code 0 or if it is configured not to restart).
  */
 BgwHandleStatus
 GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, pid_t *pidp)
index 79d1c506cc36eb20cd6b4f793db4c14b4dc92cb6..a5d5c2dbcb62b1b5eb858d49fa4700d13e752fc3 100644 (file)
@@ -2845,11 +2845,17 @@ CleanupBackgroundWorker(int pid,
                snprintf(namebuf, MAXPGPATH, "%s: %s", _("worker process"),
                                 rw->rw_worker.bgw_name);
 
-               /* Delay restarting any bgworker that exits with a nonzero status. */
                if (!EXIT_STATUS_0(exitstatus))
+               {
+                       /* Record timestamp, so we know when to restart the worker. */
                        rw->rw_crashed_at = GetCurrentTimestamp();
+               }
                else
+               {
+                       /* Zero exit status means terminate */
                        rw->rw_crashed_at = 0;
+                       rw->rw_terminate = true;
+               }
 
                /*
                 * Additionally, for shared-memory-connected workers, just like a
index c9550cc887080178f9b5023eae6a1fc8ffc5ffa0..a3b3d5f1a3c0d66bceb2fc313ca8dc479ddd6e54 100644 (file)
  * that the failure can only be transient (fork failure due to high load,
  * memory pressure, too many processes, etc); more permanent problems, like
  * failure to connect to a database, are detected later in the worker and dealt
- * with just by having the worker exit normally.  A worker which exits with a
- * return code of 0 will be immediately restarted by the postmaster.  A worker
- * which exits with a return code of 1 will be restarted after the configured
- * restart interval, or never if that interval is set to BGW_NEVER_RESTART.
+ * with just by having the worker exit normally. A worker which exits with
+ * a return code of 0 will never be restarted and will be removed from worker
+ * list. A worker which exits with a return code of 1 will be restarted after
+ * the configured restart interval (unless that interval is BGW_NEVER_RESTART).
  * The TerminateBackgroundWorker() function can be used to terminate a
  * dynamically registered background worker; the worker will be sent a SIGTERM
  * and will not be restarted after it exits.  Whenever the postmaster knows