From 1921a4f3e8830aa894883140f1e7ff963ffc088e Mon Sep 17 00:00:00 2001 From: Zhijie Hou Date: Fri, 5 Dec 2025 17:53:50 +0800 Subject: [PATCH v1] Fix LOCK_TIMEOUT handling in slotsync worker. Previously, the slotsync worker used SIGINT to receive a graceful shutdown signal from the startup process on promotion. However, SIGINT is also used by the LOCK_TIMEOUT handler to trigger a query-cancel interrupt, creating an overlap that caused the slotsync worker to overlook LOCK_TIMEOUT signals. This patch resolves this by replacing the current signal handler with the appropriate StatementCancelHandler for SIGINT within the slotsync worker. Furthermore, it updates the startup process to send a SIGUSR1 signal to notify slotsync of the need to stop during promotion. The slotsync worker now stops upon detecting that the shared memory flag (stopSignaled) is set to true. --- src/backend/replication/logical/slotsync.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/backend/replication/logical/slotsync.c b/src/backend/replication/logical/slotsync.c index 31d7cb3ca77..28629ea9c07 100644 --- a/src/backend/replication/logical/slotsync.c +++ b/src/backend/replication/logical/slotsync.c @@ -1254,10 +1254,10 @@ ProcessSlotSyncInterrupts(void) { CHECK_FOR_INTERRUPTS(); - if (ShutdownRequestPending) + if (SlotSyncCtx->stopSignaled) { ereport(LOG, - errmsg("replication slot synchronization worker is shutting down on receiving SIGINT")); + errmsg("replication slot synchronization worker is shutting down because promotion is triggered")); proc_exit(0); } @@ -1488,7 +1488,7 @@ ReplSlotSyncWorkerMain(const void *startup_data, size_t startup_data_len) /* Setup signal handling */ pqsignal(SIGHUP, SignalHandlerForConfigReload); - pqsignal(SIGINT, SignalHandlerForShutdownRequest); + pqsignal(SIGINT, StatementCancelHandler); pqsignal(SIGTERM, die); pqsignal(SIGFPE, FloatExceptionHandler); pqsignal(SIGUSR1, procsignal_sigusr1_handler); @@ -1595,7 +1595,8 @@ ReplSlotSyncWorkerMain(const void *startup_data, size_t startup_data_len) /* * The slot sync worker can't get here because it will only stop when it - * receives a SIGINT from the startup process, or when there is an error. + * receives a stop request from the startup process, or when there is an + * error. */ Assert(false); } @@ -1680,8 +1681,12 @@ ShutDownSlotSync(void) SpinLockRelease(&SlotSyncCtx->mutex); + /* + * Signal slotsync worker if it was still running. The worker will stop upon + * detecting that the stopSignaled flag is set to true. + */ if (worker_pid != InvalidPid) - kill(worker_pid, SIGINT); + kill(worker_pid, SIGUSR1); /* Wait for slot sync to end */ for (;;) -- 2.51.1.windows.1