Skip to content

Commit be75581

Browse files
committed
When a background worker exists with code 0, unregister it.
The previous behavior was to restart immediately, which was generally viewed as less useful. Petr Jelinek, with some adjustments by me.
1 parent 7572b77 commit be75581

File tree

4 files changed

+23
-11
lines changed

4 files changed

+23
-11
lines changed

doc/src/sgml/bgworker.sgml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,16 @@ typedef struct BackgroundWorker
166166
</para>
167167

168168
<para>
169-
Background workers are expected to be continuously running; if they exit
170-
cleanly, <command>postgres</> will restart them immediately. Consider doing
171-
interruptible sleep when they have nothing to do; this can be achieved by
172-
calling <function>WaitLatch()</function>. Make sure the
169+
If <structfield>bgw_restart_time</structfield> for a background worker is
170+
configured as <literal>BGW_NEVER_RESTART</>, or if it exits with an exit
171+
code of 0 or is terminated by <function>TerminateBackgroundWorker</>,
172+
it will be automatically unregistered by the postmaster on exit.
173+
Otherwise, it will be restarted after the time period configured via
174+
<structfield>bgw_restart_time</>, or immediately if the postmaster
175+
reinitializes the cluster due to a backend failure. Backends which need
176+
to suspend execution only temporarily should use an interruptible sleep
177+
rather than exiting; this can be achieved by calling
178+
<function>WaitLatch()</function>. Make sure the
173179
<literal>WL_POSTMASTER_DEATH</> flag is set when calling that function, and
174180
verify the return code for a prompt exit in the emergency case that
175181
<command>postgres</> itself has terminated.

src/backend/postmaster/bgworker.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -884,8 +884,8 @@ RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
884884
* running but is no longer.
885885
*
886886
* In the latter case, the worker may be stopped temporarily (if it is
887-
* configured for automatic restart, or if it exited with code 0) or gone
888-
* for good (if it is configured not to restart and exited with code 1).
887+
* configured for automatic restart and exited non-zero) or gone for
888+
* good (if it exited with code 0 or if it is configured not to restart).
889889
*/
890890
BgwHandleStatus
891891
GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, pid_t *pidp)

src/backend/postmaster/postmaster.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2845,11 +2845,17 @@ CleanupBackgroundWorker(int pid,
28452845
snprintf(namebuf, MAXPGPATH, "%s: %s", _("worker process"),
28462846
rw->rw_worker.bgw_name);
28472847

2848-
/* Delay restarting any bgworker that exits with a nonzero status. */
28492848
if (!EXIT_STATUS_0(exitstatus))
2849+
{
2850+
/* Record timestamp, so we know when to restart the worker. */
28502851
rw->rw_crashed_at = GetCurrentTimestamp();
2852+
}
28512853
else
2854+
{
2855+
/* Zero exit status means terminate */
28522856
rw->rw_crashed_at = 0;
2857+
rw->rw_terminate = true;
2858+
}
28532859

28542860
/*
28552861
* Additionally, for shared-memory-connected workers, just like a

src/include/postmaster/bgworker.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
* that the failure can only be transient (fork failure due to high load,
1717
* memory pressure, too many processes, etc); more permanent problems, like
1818
* failure to connect to a database, are detected later in the worker and dealt
19-
* with just by having the worker exit normally. A worker which exits with a
20-
* return code of 0 will be immediately restarted by the postmaster. A worker
21-
* which exits with a return code of 1 will be restarted after the configured
22-
* restart interval, or never if that interval is set to BGW_NEVER_RESTART.
19+
* with just by having the worker exit normally. A worker which exits with
20+
* a return code of 0 will never be restarted and will be removed from worker
21+
* list. A worker which exits with a return code of 1 will be restarted after
22+
* the configured restart interval (unless that interval is BGW_NEVER_RESTART).
2323
* The TerminateBackgroundWorker() function can be used to terminate a
2424
* dynamically registered background worker; the worker will be sent a SIGTERM
2525
* and will not be restarted after it exits. Whenever the postmaster knows

0 commit comments

Comments
 (0)