OSDN Git Service

Additional test for each commit in sync rep path to plug minute
authorSimon Riggs <simon@2ndQuadrant.com>
Sat, 26 Mar 2011 10:09:37 +0000 (10:09 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Sat, 26 Mar 2011 10:09:37 +0000 (10:09 +0000)
possibility of race condition that would effect performance only.
Requested by Robert Haas. Re-arrange related comments.

src/backend/replication/syncrep.c

index e99b43d..17c2554 100644 (file)
@@ -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();