Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Always treat a standby returning an an invalid flush location as async
authorMagnus Hagander <magnus@hagander.net>
Wed, 4 Jul 2012 13:10:46 +0000 (15:10 +0200)
committerMagnus Hagander <magnus@hagander.net>
Wed, 4 Jul 2012 13:14:57 +0000 (15:14 +0200)
This ensures that a standby such as pg_receivexlog will not be selected
as sync standby - which would cause the master to block waiting for
a location that could never happen.

Fujii Masao

src/backend/replication/syncrep.c
src/backend/replication/walreceiver.c
src/backend/replication/walsender.c

index a3319642c628e99aef7c5cf55b40d2ddb907bbe5..088f7b67f91309cb9c37856c0fbe14ae3b486397 100644 (file)
@@ -377,10 +377,12 @@ SyncRepReleaseWaiters(void)
    /*
     * If this WALSender is serving a standby that is not on the list of
     * potential standbys then we have nothing to do. If we are still starting
-    * up or still running base backup, then leave quickly also.
+    * up, still running base backup or the current flush position is still
+    * invalid, then leave quickly also.
     */
    if (MyWalSnd->sync_standby_priority == 0 ||
-       MyWalSnd->state < WALSNDSTATE_STREAMING)
+       MyWalSnd->state < WALSNDSTATE_STREAMING ||
+       XLogRecPtrIsInvalid(MyWalSnd->flush))
        return;
 
    /*
@@ -400,7 +402,8 @@ SyncRepReleaseWaiters(void)
            walsnd->state == WALSNDSTATE_STREAMING &&
            walsnd->sync_standby_priority > 0 &&
            (priority == 0 ||
-            priority > walsnd->sync_standby_priority))
+            priority > walsnd->sync_standby_priority) &&
+           !XLogRecPtrIsInvalid(walsnd->flush))
        {
            priority = walsnd->sync_standby_priority;
            syncWalSnd = walsnd;
index 650b74fff7d5ca5b6201abfce8efffd332f04d64..0996d6d59484f6b474c0277c7e87dc80776cd42b 100644 (file)
@@ -280,6 +280,11 @@ WalReceiverMain(void)
    walrcv_connect(conninfo, startpoint);
    DisableWalRcvImmediateExit();
 
+   /* Initialize LogstreamResult, reply_message and feedback_message */
+   LogstreamResult.Write = LogstreamResult.Flush = GetXLogReplayRecPtr(NULL);
+   MemSet(&reply_message, 0, sizeof(reply_message));
+   MemSet(&feedback_message, 0, sizeof(feedback_message));
+
    /* Loop until end-of-streaming or error */
    for (;;)
    {
index 45a3b2ef2941063d9901d1f060a73c2e3897c751..16c2a7681ec0948ef12051624f5dc27b69cfebb2 100644 (file)
@@ -1530,12 +1530,19 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 
        if (walsnd->pid != 0)
        {
-           sync_priority[i] = walsnd->sync_standby_priority;
+           /*
+            * Treat a standby such as a pg_basebackup background process
+            * which always returns an invalid flush location, as an
+            * asynchronous standby.
+            */
+           sync_priority[i] = XLogRecPtrIsInvalid(walsnd->flush) ?
+               0 : walsnd->sync_standby_priority;
 
            if (walsnd->state == WALSNDSTATE_STREAMING &&
                walsnd->sync_standby_priority > 0 &&
                (priority == 0 ||
-                priority > walsnd->sync_standby_priority))
+                priority > walsnd->sync_standby_priority) &&
+               !XLogRecPtrIsInvalid(walsnd->flush))
            {
                priority = walsnd->sync_standby_priority;
                sync_standby = i;