summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Riggs2014-07-15 13:45:44 +0000
committerSimon Riggs2014-07-15 13:45:44 +0000
commit8ebf5f7206e0e4c5d4113cf67d3db8f2a90d7e0f (patch)
tree4385426275226db458d40de3c4351473bffe6bfe
parentbfb47043ad3a3adf50c19011b855afccc2ba6f8d (diff)
Reset master xmin when hot_standby_feedback disabled.
If walsender has xmin of standby then ensure we reset the value to 0 when we change from hot_standby_feedback=on to hot_standby_feedback=off.
-rw-r--r--doc/src/sgml/protocol.sgml5
-rw-r--r--src/backend/replication/walreceiver.c44
-rw-r--r--src/backend/replication/walsender.c5
3 files changed, 41 insertions, 13 deletions
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index e7438809309..8a0755eea98 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -1584,7 +1584,10 @@ The commands accepted in walsender mode are:
</term>
<listitem>
<para>
- The standby's current xmin.
+ The standby's current xmin. This may be 0, if the standby is
+ sending notification that Hot Standby feedback will no
+ longer be sent on this connection. Later non-zero messages may
+ reinitiate the feedback mechanism.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index d2ac547602b..3dfc3d64576 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -124,7 +124,7 @@ static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
static void XLogWalRcvFlush(bool dying);
static void XLogWalRcvSendReply(void);
-static void XLogWalRcvSendHSFeedback(void);
+static void XLogWalRcvSendHSFeedback(bool immed);
/* Signal handlers */
static void WalRcvSigHupHandler(SIGNAL_ARGS);
@@ -310,6 +310,7 @@ WalReceiverMain(void)
{
got_SIGHUP = false;
ProcessConfigFile(PGC_SIGHUP);
+ XLogWalRcvSendHSFeedback(true);
}
/* Wait a while for data to arrive */
@@ -338,7 +339,7 @@ WalReceiverMain(void)
* master anyway, to report any progress in applying WAL.
*/
XLogWalRcvSendReply();
- XLogWalRcvSendHSFeedback();
+ XLogWalRcvSendHSFeedback(false);
}
}
}
@@ -591,7 +592,7 @@ XLogWalRcvFlush(bool dying)
if (!dying)
{
XLogWalRcvSendReply();
- XLogWalRcvSendHSFeedback();
+ XLogWalRcvSendHSFeedback(false);
}
}
}
@@ -651,45 +652,62 @@ XLogWalRcvSendReply(void)
/*
* Send hot standby feedback message to primary, plus the current time,
* in case they don't have a watch.
+ *
+ * If the user disables feedback, send one final message to tell sender
+ * to forget about the xmin on this standby.
*/
static void
-XLogWalRcvSendHSFeedback(void)
+XLogWalRcvSendHSFeedback(bool immed)
{
char buf[sizeof(StandbyHSFeedbackMessage) + 1];
TimestampTz now;
TransactionId nextXid;
uint32 nextEpoch;
TransactionId xmin;
+ static TimestampTz sendTime = 0;
+ static bool master_has_standby_xmin = false;
/*
* If the user doesn't want status to be reported to the master, be sure
* to exit before doing anything at all.
*/
- if (wal_receiver_status_interval <= 0 || !hot_standby_feedback)
+ if ((wal_receiver_status_interval <= 0 || !hot_standby_feedback) &&
+ !master_has_standby_xmin)
return;
/* Get current timestamp. */
now = GetCurrentTimestamp();
- /*
- * Send feedback at most once per wal_receiver_status_interval.
- */
- if (!TimestampDifferenceExceeds(feedback_message.sendTime, now,
+ if (!immed)
+ {
+ /*
+ * Send feedback at most once per wal_receiver_status_interval.
+ */
+ if (!TimestampDifferenceExceeds(sendTime, now,
wal_receiver_status_interval * 1000))
- return;
+ return;
+ }
+
+ sendTime = now;
/*
* If Hot Standby is not yet active there is nothing to send. Check this
* after the interval has expired to reduce number of calls.
*/
if (!HotStandbyActive())
+ {
+ Assert(!master_has_standby_xmin);
return;
+ }
/*
* Make the expensive call to get the oldest xmin once we are certain
* everything else has been checked.
*/
- xmin = GetOldestXmin(true, false);
+ if (hot_standby_feedback)
+ xmin = GetOldestXmin(true, false);
+ else
+ xmin = InvalidTransactionId;
/*
* Get epoch and adjust if nextXid and oldestXmin are different sides of
@@ -714,4 +732,8 @@ XLogWalRcvSendHSFeedback(void)
buf[0] = 'h';
memcpy(&buf[1], &feedback_message, sizeof(StandbyHSFeedbackMessage));
walrcv_send(buf, sizeof(StandbyHSFeedbackMessage) + 1);
+ if (TransactionIdIsValid(xmin))
+ master_has_standby_xmin = true;
+ else
+ master_has_standby_xmin = false;
}
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index a5683302d56..4a5f01d8bed 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -623,9 +623,12 @@ ProcessStandbyHSFeedbackMessage(void)
reply.xmin,
reply.epoch);
- /* Ignore invalid xmin (can't actually happen with current walreceiver) */
+ /* Unset WalSender's xmin if the feedback message value is invalid */
if (!TransactionIdIsNormal(reply.xmin))
+ {
+ MyProc->xmin = InvalidTransactionId;
return;
+ }
/*
* Check that the provided xmin/epoch are sane, that is, not in the future