summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Riggs2011-03-26 10:09:37 +0000
committerSimon Riggs2011-03-26 10:09:37 +0000
commit92f4786fa9b730fd12cbfe973eb96addc6e98924 (patch)
tree3286d66011a30fd982aae2cf96bf7ecc48947e4b
parentbfa4440ca5d948c4d4f0ab5bb82d433200c35288 (diff)
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.
-rw-r--r--src/backend/replication/syncrep.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e99b43d8e0..17c255480e 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();