postgres.git / summary / log / commit / refs

commit    d62dca3b297413a11a594c9675f2fb22e931d01b
Author:   Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date:     Wed Feb 18 17:59:34 2026 +0000

    Use standard die() handler for SIGTERM in bgworkers
    
    The previous default bgworker_die() signal would exit with elog(FATAL)
    directly from the signal handler. That could cause deadlocks or
    crashes if the signal handler runs while we're e.g holding a spinlock
    or in the middle of a memory allocation.
    
    All the built-in background workers overrode that to use the normal
    die() handler and CHECK_FOR_INTERRUPTS(). Let's make that the default
    for all background workers. Some extensions relying on the old
    behavior might need to adapt, but the new default is much safer and is
    the right thing to do for most background workers.
    
    Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
    Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
    Discussion: https://www.postgresql.org/message-id/5238fe45-e486-4c62-a7f3-c7d8d416e812@iki.fi


doc/src/sgml/bgworker.sgml | 10 ++++++++++ src/backend/access/transam/parallel.c | 1 - src/backend/postmaster/bgworker.c | 16 +--------------- src/backend/replication/logical/applyparallelworker.c | 1 - src/backend/replication/logical/launcher.c | 1 - src/backend/replication/logical/worker.c | 1 - src/test/modules/test_shm_mq/worker.c | 8 +------- 7 files changed, 12 insertions(+), 26 deletions(-) diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml index 4699ef6345f..2affba74382 100644 --- a/doc/src/sgml/bgworker.sgml +++ b/doc/src/sgml/bgworker.sgml @@ -232,6 +232,8 @@ typedef struct BackgroundWorker </para> <para> + A well-behaved background worker must react promptly to standard signals + that the postmaster uses to control its child processes. Signals are initially blocked when control reaches the background worker's main function, and must be unblocked by it; this is to allow the process to customize its signal handlers, if necessary. @@ -240,6 +242,14 @@ typedef struct BackgroundWorker <function>BackgroundWorkerBlockSignals</function>. </para> + <para> + The default signal handlers merely set interrupt flags + that are processed later by <function>CHECK_FOR_INTERRUPTS()</function>. + <function>CHECK_FOR_INTERRUPTS()</function> should be called in any + long-running loop to ensure that the background worker doesn't prevent the + system from shutting down in a timely fashion. + </para> + <para> If <structfield>bgw_restart_time</structfield> for a background worker is configured as <literal>BGW_NEVER_RESTART</literal>, or if it exits with an exit diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index fe00488487d..44786dc131f 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -1327,7 +1327,6 @@ ParallelWorkerMain(Datum main_arg) InitializingParallelWorker = true; /* Establish signal handlers. */ - pqsignal(SIGTERM, die); BackgroundWorkerUnblockSignals(); /* Determine and set our parallel worker number. */ diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 261ccd3f59c..8678ea4e139 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -718,20 +718,6 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel) return true; } -/* - * Standard SIGTERM handler for background workers - */ -static void -bgworker_die(SIGNAL_ARGS) -{ - sigprocmask(SIG_SETMASK, &BlockSig, NULL); - - ereport(FATAL, - (errcode(ERRCODE_ADMIN_SHUTDOWN), - errmsg("terminating background worker \"%s\" due to administrator command", - MyBgworkerEntry->bgw_type))); -} - /* * Main entry point for background worker processes. */ @@ -787,7 +773,7 @@ BackgroundWorkerMain(const void *startup_data, size_t startup_data_len) pqsignal(SIGUSR1, SIG_IGN); pqsignal(SIGFPE, SIG_IGN); } - pqsignal(SIGTERM, bgworker_die); + pqsignal(SIGTERM, die); /* SIGQUIT handler was already set up by InitPostmasterChild */ pqsignal(SIGHUP, SIG_IGN); diff --git a/src/backend/replication/logical/applyparallelworker.c b/src/backend/replication/logical/applyparallelworker.c index 8a01f16a2ca..1730ace5490 100644 --- a/src/backend/replication/logical/applyparallelworker.c +++ b/src/backend/replication/logical/applyparallelworker.c @@ -879,7 +879,6 @@ ParallelApplyWorkerMain(Datum main_arg) * receiving SIGTERM. */ pqsignal(SIGHUP, SignalHandlerForConfigReload); - pqsignal(SIGTERM, die); pqsignal(SIGUSR2, SignalHandlerForShutdownRequest); BackgroundWorkerUnblockSignals(); diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 3ed86480be2..e6112e11ec2 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -1213,7 +1213,6 @@ ApplyLauncherMain(Datum main_arg) /* Establish signal handlers. */ pqsignal(SIGHUP, SignalHandlerForConfigReload); - pqsignal(SIGTERM, die); BackgroundWorkerUnblockSignals(); /* diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 8b93f48470c..f179d081846 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -5890,7 +5890,6 @@ SetupApplyOrSyncWorker(int worker_slot) /* Setup signal handling */ pqsignal(SIGHUP, SignalHandlerForConfigReload); - pqsignal(SIGTERM, die); BackgroundWorkerUnblockSignals(); /* diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index 368e4f3f234..6a4147554bb 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -54,13 +54,7 @@ test_shm_mq_main(Datum main_arg) int myworkernumber; PGPROC *registrant; - /* - * Establish signal handlers. - * - * We want CHECK_FOR_INTERRUPTS() to kill off this worker process just as - * it would a normal user backend. To make that happen, we use die(). - */ - pqsignal(SIGTERM, die); + /* Unblock signals. The standard signal handlers are OK for us. */ BackgroundWorkerUnblockSignals(); /* [parent: 3894f08abe49]