From 00b784778fb8034adfcc7a98776299dc9734b0d1 Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Sat, 10 Jan 2026 05:46:38 -0800 Subject: [PATCH] fix(worker): prevent rapid manager cycling for databases without extension When pglogical is loaded via shared_preload_libraries, manager workers were rapidly cycling (start, exit, restart) for databases that don't have the extension installed. This caused excessive log noise and wasted resources. The fix adds a skip_supervisor_wakeup flag to prevent the supervisor from being woken immediately when a manager exits due to missing extension. The supervisor will restart managers on its normal timeout (30s Windows, 180s Unix) instead. --- pglogical_manager.c | 8 ++++++++ pglogical_worker.c | 10 +++++++++- pglogical_worker.h | 7 +++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/pglogical_manager.c b/pglogical_manager.c index bbf97d45..b5dfb208 100644 --- a/pglogical_manager.c +++ b/pglogical_manager.c @@ -251,7 +251,15 @@ pglogical_manager_main(Datum main_arg) /* If the extension is still not installed after retries, exit. */ if (!OidIsValid(extoid)) + { + /* + * Mark that we're exiting due to missing extension so the detach + * handler doesn't wake the supervisor. This prevents rapid restart + * cycles for databases that don't have pglogical installed. + */ + MyPGLogicalWorker->skip_supervisor_wakeup = true; proc_exit(0); + } StartTransactionCommand(); diff --git a/pglogical_worker.c b/pglogical_worker.c index 8ac47e45..0d0ef8e8 100644 --- a/pglogical_worker.c +++ b/pglogical_worker.c @@ -139,6 +139,7 @@ pglogical_worker_register(PGLogicalWorker *worker) worker_shm->crashed_at = 0; worker_shm->proc = NULL; worker_shm->worker_type = worker->worker_type; + worker_shm->skip_supervisor_wakeup = false; LWLockRelease(PGLogicalCtx->lock); @@ -462,12 +463,19 @@ pglogical_worker_detach(bool crash) * Worker has finished work, clean up its state from shmem. * If this was a manager, notify the supervisor so it can restart * the manager if needed (e.g., if the database still has subscriptions). + * + * However, if skip_supervisor_wakeup is set, the manager is exiting + * because the extension isn't installed in this database. Don't wake + * the supervisor immediately - let it restart on its normal timeout. + * This prevents rapid cycling for databases without pglogical. */ - if (MyPGLogicalWorker->worker_type == PGLOGICAL_WORKER_MANAGER) + if (MyPGLogicalWorker->worker_type == PGLOGICAL_WORKER_MANAGER && + !MyPGLogicalWorker->skip_supervisor_wakeup) PGLogicalCtx->subscriptions_changed = true; MyPGLogicalWorker->worker_type = PGLOGICAL_WORKER_NONE; MyPGLogicalWorker->dboid = InvalidOid; + MyPGLogicalWorker->skip_supervisor_wakeup = false; } /* diff --git a/pglogical_worker.h b/pglogical_worker.h index e2bb5b3f..ba5973f6 100644 --- a/pglogical_worker.h +++ b/pglogical_worker.h @@ -54,6 +54,13 @@ typedef struct PGLogicalWorker { /* Database id to connect to. */ Oid dboid; + /* + * Set by manager before exiting due to missing extension. + * Prevents supervisor from being woken immediately, avoiding + * rapid restart cycles for databases without pglogical. + */ + bool skip_supervisor_wakeup; + /* Type-specific worker info */ union {