>From 3f5bf1e2fad99081edfcb31601398af3b953cf15 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 13 Dec 2012 20:49:59 +0100
Subject: [PATCH 2/2] wal decoding: Use GetOldestXminNoLock to compute the
 initial logical xmin safely

---
 src/backend/replication/walsender.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index c1ec0a3..2204c7a 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -544,16 +544,12 @@ InitLogicalReplication(InitLogicalReplicationCmd *cmd)
 	 * cannot go backwards anymore, as ComputeLogicalXmin() nails the value
 	 * down.
 	 *
-	 * We need to do this *after* releasing the spinlock, otherwise
-	 * GetOldestXmin will deadlock with ourselves.
-	 *
-	 * FIXME: think about solving the race conditions in a nicer way.
+	 * FIXME: this should probably be in procarray.c?
 	 */
-recompute_xmin:
-	walsnd->xmin = GetOldestXmin(true, true);
+	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+	walsnd->xmin = GetOldestXminNoLock(true, true);
+	LWLockRelease(ProcArrayLock);
 	ComputeLogicalXmin();
-	if (walsnd->xmin != GetOldestXmin(true, true))
-		goto recompute_xmin;
 
 	decoding_ctx = AllocSetContextCreate(TopMemoryContext,
 										 "decoding context",
@@ -1133,8 +1129,10 @@ ProcessStandbyReplyMessage(void)
 	}
 
 	/*
-	 * Do an unlocked check for candidate_xmin first.
+	 * Advance our local xmin horizin when the client confirmed a flush.
 	 */
+
+	/* Do an unlocked check for candidate_xmin first.*/
 	if (MyLogicalWalSnd &&
 		TransactionIdIsValid(MyLogicalWalSnd->candidate_xmin))
 	{
-- 
1.7.12.289.g0ce9864.dirty

