]> granicus.if.org Git - postgresql/commitdiff
Fix bug in clean shutdown of walsender that pg_receiving is connecting to.
authorFujii Masao <fujii@postgresql.org>
Mon, 17 Mar 2014 11:42:35 +0000 (20:42 +0900)
committerFujii Masao <fujii@postgresql.org>
Mon, 17 Mar 2014 11:42:35 +0000 (20:42 +0900)
On clean shutdown, walsender waits for all WAL to be replicated to a standby,
and exits. It determined whether that replication had been completed by
checking whether its sent location had been equal to a standby's flush
location. Unfortunately this condition never becomes true when the standby
such as pg_receivexlog which always returns an invalid flush location is
connecting to walsender, and then walsender waits forever.

This commit changes walsender so that it just checks a standby's write
location if a flush location is invalid.

Back-patch to 9.1 where enough infrastructure for this exists.

src/backend/replication/walsender.c

index 7b44f9b0443748f8f215d621b5424c3a92aa7279..b6bf6333378ffc8e559853ecd8b5ac39a62b8971 100644 (file)
@@ -775,9 +775,20 @@ WalSndLoop(void)
                         */
                        if (walsender_ready_to_stop)
                        {
+                               XLogRecPtr      replicatedPtr;
+
                                /* ... let's just be real sure we're caught up ... */
                                XLogSend(output_message, &caughtup);
-                               if (caughtup && XLByteEQ(sentPtr, MyWalSnd->flush) &&
+
+                               /*
+                                * Check a write location to see whether all the WAL have
+                                * successfully been replicated if this walsender is connecting
+                                * to a standby such as pg_receivexlog which always returns
+                                * an invalid flush location. Otherwise, check a flush location.
+                                */
+                               replicatedPtr = XLogRecPtrIsInvalid(MyWalSnd->flush) ?
+                                       MyWalSnd->write : MyWalSnd->flush;
+                               if (caughtup && XLByteEQ(sentPtr, replicatedPtr) &&
                                        !pq_is_send_pending())
                                {
                                        walsender_shutdown_requested = true;