From 92f4786fa9b730fd12cbfe973eb96addc6e98924 Mon Sep 17 00:00:00 2001
From: Simon Riggs <simon@2ndQuadrant.com>
Date: Sat, 26 Mar 2011 10:09:37 +0000
Subject: [PATCH] Additional test for each commit in sync rep path to plug
 minute possibility of race condition that would effect performance only.
 Requested by Robert Haas. Re-arrange related comments.

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

diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e99b43d8e0d..17c255480eb 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -114,21 +114,28 @@ SyncRepWaitForLSN(XLogRecPtr XactCommitLSN)
 	/* Reset the latch before adding ourselves to the queue. */
 	ResetLatch(&MyProc->waitLatch);
 
-	/*
-	 * Set our waitLSN so WALSender will know when to wake us, and add
-	 * ourselves to the queue.
-	 */
 	LWLockAcquire(SyncRepLock, LW_EXCLUSIVE);
 	Assert(MyProc->syncRepState == SYNC_REP_NOT_WAITING);
-	if (!WalSndCtl->sync_standbys_defined)
+
+	/*
+	 * We don't wait for sync rep if WalSndCtl->sync_standbys_defined is
+	 * not set.  See SyncRepUpdateSyncStandbysDefined.
+	 *
+	 * Also check that the standby hasn't already replied. Unlikely
+	 * race condition but we'll be fetching that cache line anyway
+	 * so its likely to be a low cost check.
+	 */
+	if (!WalSndCtl->sync_standbys_defined ||
+		XLByteLE(XactCommitLSN, WalSndCtl->lsn))
 	{
-		/*
-		 * We don't wait for sync rep if WalSndCtl->sync_standbys_defined is
-		 * not set.  See SyncRepUpdateSyncStandbysDefined.
-		 */
 		LWLockRelease(SyncRepLock);
 		return;
 	}
+
+	/*
+	 * Set our waitLSN so WALSender will know when to wake us, and add
+	 * ourselves to the queue.
+	 */
 	MyProc->waitLSN = XactCommitLSN;
 	MyProc->syncRepState = SYNC_REP_WAITING;
 	SyncRepQueueInsert();
-- 
GitLab