From 92f4786fa9b730fd12cbfe973eb96addc6e98924 Mon Sep 17 00:00:00 2001 From: Simon Riggs 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 | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 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); + LWLockAcquire(SyncRepLock, LW_EXCLUSIVE); + Assert(MyProc->syncRepState == SYNC_REP_NOT_WAITING); + + /* + * 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)) + { + LWLockRelease(SyncRepLock); + return; + } + /* * 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. - */ - LWLockRelease(SyncRepLock); - return; - } MyProc->waitLSN = XactCommitLSN; MyProc->syncRepState = SYNC_REP_WAITING; SyncRepQueueInsert();