From c1a32b49fcfa01d3c2fc4fc904388815b9cee418 Mon Sep 17 00:00:00 2001
From: Ajin Cherian <itsajin@gmail.com>
Date: Mon, 14 Jul 2025 06:04:38 -0400
Subject: [PATCH] Fix a possible deadlock during ALTER SUBSCRIPTION ... DROP
 PUBLICATION

In most situations the tablesync worker will drop the corresponding origin before it
finishes executing, but if an error causes the tablesync worker to fail just prior to
dropping the origin, the apply worker will later find the origin and drop it. During this
time if the user simultaneously does ALTER SUBSCRIPTION ... DROP PUBLICATION, there is a
possibility of a deadlock between the apply worker and the user process, because of the
order in which the locks are taken. The ALTER SUBSCRIPTION code takes a AccessExclusiveLock
on SubscriptionRelationId initially and now the fix is for the apply worker to also
take an AccessShareLock on SubscriptionRelationId prior to dropping any origins.
---
 src/backend/replication/logical/tablesync.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index e4fd634..6a98c7e 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -122,6 +122,7 @@
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 #include "utils/usercontext.h"
+#include "utils/injection_point.h"
 
 typedef enum
 {
@@ -492,7 +493,13 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn)
 				 * worker to remove the origin tracking as if there is any
 				 * error while dropping we won't restart it to drop the
 				 * origin. So passing missing_ok = true.
+				 *
+				 * Also lock SubscriptionRelationId with AccessShareLock to
+				 * prevent any deadlocks with the user concurrently performing
+				 * refresh on the subscription.
 				 */
+				LockSharedObject(SubscriptionRelationId, MyLogicalRepWorker->subid,
+								 0, AccessShareLock);
 				ReplicationOriginNameForLogicalRep(MyLogicalRepWorker->subid,
 												   rstate->relid,
 												   originname,
-- 
1.8.3.1

