]> granicus.if.org Git - postgresql/commitdiff
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:42 +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 0bb4145cb0c4cc6ec5c35dc49af1d947431a5be9..a61725eed6982636b33d5af047a40f29ce2a1651 100644 (file)
@@ -376,10 +376,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;
 
        /*
@@ -399,7 +401,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 f3de9bdf466db01862b0f9e2f1688b4bccc6aca1..eb96f6dd331e2d3d942f6cedb30b2455bf769148 100644 (file)
@@ -281,6 +281,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 912ce9d450380682e064f241b857bf608c375359..d007f5f6fa1865cdd7be4446eecc60c33ebe1430 100644 (file)
@@ -1510,12 +1510,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;