From edff42cb08bcd18c4e9b593ec23504532f7431f2 Mon Sep 17 00:00:00 2001 From: Baji Shaik Date: Tue, 12 May 2026 01:27:46 +0000 Subject: [PATCH v2 1/1] Fix REPACK decoding worker not cleaned up on FATAL exit When the launching backend of REPACK (CONCURRENTLY) is terminated via pg_terminate_backend(), ProcDiePending causes ereport(FATAL) which bypasses PG_FINALLY blocks. As a result, stop_repack_decoding_worker() is never called, leaving the decoding worker running indefinitely and holding its temporary replication slot. Fix by registering a before_shmem_exit callback when the decoding worker is started. The callback calls stop_repack_decoding_worker(), which terminates the worker and waits for it to shut down. Since before_shmem_exit runs while shared memory is still attached, WaitForBackgroundWorkerShutdown() is safe to call at this stage. --- src/backend/commands/repack.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 860e2aecbe9..5e6494bf561 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -64,6 +64,7 @@ #include "pgstat.h" #include "replication/logicalrelation.h" #include "storage/bufmgr.h" +#include "storage/ipc.h" #include "storage/lmgr.h" #include "storage/predicate.h" #include "storage/proc.h" @@ -211,6 +212,7 @@ static Oid determine_clustered_index(Relation rel, bool usingindex, static void start_repack_decoding_worker(Oid relid); static void stop_repack_decoding_worker(void); +static void repack_decoding_worker_exit_cleanup(int code, Datum arg); static Snapshot get_initial_snapshot(DecodingWorker *worker); static void ProcessRepackMessage(StringInfo msg); @@ -3454,6 +3456,8 @@ start_repack_decoding_worker(Oid relid) decoding_worker->seg = seg; decoding_worker->error_mqh = mqh; + before_shmem_exit(repack_decoding_worker_exit_cleanup, (Datum) 0); + /* * The decoding setup must be done before the caller can have XID assigned * for any reason, otherwise the worker might end up in a deadlock, @@ -3477,6 +3481,17 @@ start_repack_decoding_worker(Oid relid) ConditionVariableCancelSleep(); } +/* + * before_shmem_exit callback to stop the repack decoding worker. Needed + * because SIGTERM (e.g., pg_terminate_backend) causes a FATAL exit, which + * bypasses PG_FINALLY blocks. + */ +static void +repack_decoding_worker_exit_cleanup(int code, Datum arg) +{ + stop_repack_decoding_worker(); +} + /* * Stop the decoding worker and cleanup the related resources. * -- 2.50.1 (Apple Git-155)