From 8c8adf4aa43d6c0da2243aea65d3dc508c79a933 Mon Sep 17 00:00:00 2001 From: Magnus Hagander <magnus@hagander.net> Date: Wed, 4 Jul 2012 15:10:46 +0200 Subject: [PATCH] Always treat a standby returning an an invalid flush location as async 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 | 9 ++++++--- src/backend/replication/walreceiver.c | 5 +++++ src/backend/replication/walsender.c | 11 +++++++++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index a3319642c62..088f7b67f91 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -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; diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 650b74fff7d..0996d6d5948 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -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 (;;) { diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 45a3b2ef294..16c2a7681ec 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -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; -- GitLab