*/
 void
 UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
-                          XLogRecPtr sublsn)
+                          XLogRecPtr sublsn, bool already_locked)
 {
    Relation    rel;
    HeapTuple   tup;
    Datum       values[Natts_pg_subscription_rel];
    bool        replaces[Natts_pg_subscription_rel];
 
-   LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
+   if (already_locked)
+   {
+#ifdef USE_ASSERT_CHECKING
+       LOCKTAG     tag;
 
-   rel = table_open(SubscriptionRelRelationId, RowExclusiveLock);
+       Assert(CheckRelationOidLockedByMe(SubscriptionRelRelationId,
+                                         RowExclusiveLock, true));
+       SET_LOCKTAG_OBJECT(tag, InvalidOid, SubscriptionRelationId, subid, 0);
+       Assert(LockHeldByMe(&tag, AccessShareLock, true));
+#endif
+
+       rel = table_open(SubscriptionRelRelationId, NoLock);
+   }
+   else
+   {
+       LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
+       rel = table_open(SubscriptionRelRelationId, RowExclusiveLock);
+   }
 
    /* Try finding existing mapping. */
    tup = SearchSysCacheCopy2(SUBSCRIPTIONRELMAP,
 
        UpdateSubscriptionRelState(MyLogicalRepWorker->subid,
                                   MyLogicalRepWorker->relid,
                                   MyLogicalRepWorker->relstate,
-                                  MyLogicalRepWorker->relstate_lsn);
+                                  MyLogicalRepWorker->relstate_lsn,
+                                  false);
 
        /*
         * End streaming so that LogRepWorkerWalRcvConn can be used to drop
    ListCell   *lc;
    bool        started_tx = false;
    bool        should_exit = false;
+   Relation    rel = NULL;
 
    Assert(!IsTransactionState());
 
                 * 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.
+                *
+                * Lock the subscription and origin in the same order as we
+                * are doing during DDL commands to avoid deadlocks. See
+                * AlterSubscription_refresh.
                 */
+               LockSharedObject(SubscriptionRelationId, MyLogicalRepWorker->subid,
+                                0, AccessShareLock);
+
+               if (!rel)
+                   rel = table_open(SubscriptionRelRelationId, RowExclusiveLock);
+
                ReplicationOriginNameForLogicalRep(MyLogicalRepWorker->subid,
                                                   rstate->relid,
                                                   originname,
                 */
                UpdateSubscriptionRelState(MyLogicalRepWorker->subid,
                                           rstate->relid, rstate->state,
-                                          rstate->lsn);
+                                          rstate->lsn, true);
            }
        }
        else
                         * This is required to avoid any undetected deadlocks
                         * due to any existing lock as deadlock detector won't
                         * be able to detect the waits on the latch.
+                        *
+                        * Also close any tables prior to the commit.
                         */
+                       if (rel)
+                       {
+                           table_close(rel, NoLock);
+                           rel = NULL;
+                       }
                        CommitTransactionCommand();
                        pgstat_report_stat(false);
                    }
        }
    }
 
+   /* Close table if opened */
+   if (rel)
+       table_close(rel, NoLock);
+
+
    if (started_tx)
    {
        /*
    UpdateSubscriptionRelState(MyLogicalRepWorker->subid,
                               MyLogicalRepWorker->relid,
                               MyLogicalRepWorker->relstate,
-                              MyLogicalRepWorker->relstate_lsn);
+                              MyLogicalRepWorker->relstate_lsn,
+                              false);
    CommitTransactionCommand();
    pgstat_report_stat(true);
 
    UpdateSubscriptionRelState(MyLogicalRepWorker->subid,
                               MyLogicalRepWorker->relid,
                               SUBREL_STATE_FINISHEDCOPY,
-                              MyLogicalRepWorker->relstate_lsn);
+                              MyLogicalRepWorker->relstate_lsn,
+                              false);
 
    CommitTransactionCommand();
 
 
 extern void AddSubscriptionRelState(Oid subid, Oid relid, char state,
                                    XLogRecPtr sublsn, bool retain_lock);
 extern void UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
-                                      XLogRecPtr sublsn);
+                                      XLogRecPtr sublsn, bool already_locked);
 extern char GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn);
 extern void RemoveSubscriptionRel(Oid subid, Oid relid);