From ba90643906250dca3c684c2a8f246fcb4a70d864 Mon Sep 17 00:00:00 2001 From: Shihao Zhong Date: Sat, 5 Sep 2026 17:07:19 -0400 Subject: [PATCH v2] Pass the backend's timeout settings to the REPACK decoding worker The worker connects as the table owner in a new session, so a role- or database-level lock_timeout applies to it and cancels its wait for older transactions, and the user running REPACK cannot override it. Pass the values in effect in the backend through the shared memory segment the worker already attaches to, so that a session-level SET reaches it too. --- src/backend/commands/repack.c | 4 ++++ src/backend/commands/repack_worker.c | 13 +++++++++++++ src/include/commands/repack_internal.h | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 0533217968e..d4c5ded6485 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -3692,6 +3692,10 @@ start_repack_decoding_worker(Oid relid) shared->backend_pid = MyProcPid; shared->backend_proc_number = MyProcNumber; + /* Pass our timeouts to the worker. See RepackWorkerMain(). */ + shared->lock_timeout = LockTimeout; + shared->transaction_timeout = TransactionTimeout; + mq = shm_mq_create((char *) BUFFERALIGN(shared->error_queue), REPACK_ERROR_QUEUE_SIZE); shm_mq_set_receiver(mq, MyProc); diff --git a/src/backend/commands/repack_worker.c b/src/backend/commands/repack_worker.c index b4ba9cfc67b..6e46c479b16 100644 --- a/src/backend/commands/repack_worker.c +++ b/src/backend/commands/repack_worker.c @@ -26,6 +26,7 @@ #include "storage/ipc.h" #include "storage/proc.h" #include "tcop/tcopprot.h" +#include "utils/guc.h" #include "utils/memutils.h" #define PGREPACK_PLUGIN "pgrepack" @@ -66,6 +67,7 @@ RepackWorkerMain(Datum main_arg) LogicalDecodingContext *decoding_ctx; SharedFileSet *sfs; Snapshot snapshot; + char buf[32]; am_repack_worker = true; @@ -111,6 +113,17 @@ RepackWorkerMain(Datum main_arg) BGWORKER_BYPASS_ALLOWCONN | BGWORKER_BYPASS_ROLELOGINCHECK); + /* + * Adopt the backend's timeouts. We run in a new session as the table + * owner, so role- and database-level settings would otherwise apply here, + * and the user running REPACK could neither see nor override them. These + * are the only two settable timeouts a background worker arms. + */ + snprintf(buf, sizeof(buf), "%d", shared->lock_timeout); + SetConfigOption("lock_timeout", buf, PGC_SUSET, PGC_S_OVERRIDE); + snprintf(buf, sizeof(buf), "%d", shared->transaction_timeout); + SetConfigOption("transaction_timeout", buf, PGC_SUSET, PGC_S_OVERRIDE); + /* * Transaction is needed to open relation, and it also provides us with a * resource owner. diff --git a/src/include/commands/repack_internal.h b/src/include/commands/repack_internal.h index 42111aa4ae3..6b4906fd750 100644 --- a/src/include/commands/repack_internal.h +++ b/src/include/commands/repack_internal.h @@ -106,6 +106,10 @@ typedef struct DecodingWorkerShared pid_t backend_pid; ProcNumber backend_proc_number; + /* Timeouts in effect in the backend. See RepackWorkerMain(). */ + int lock_timeout; + int transaction_timeout; + /* * Memory the queue is located in. *