diff options
author | Simon Riggs <simon@2ndQuadrant.com> | 2013-02-04 10:29:22 +0000 |
---|---|---|
committer | Simon Riggs <simon@2ndQuadrant.com> | 2013-02-04 10:29:22 +0000 |
commit | bd56e74127dea4102d1fc761d65fefbb32146713 (patch) | |
tree | 9bc3b544a092867296e44fefc8a79af4e11e65b5 | |
parent | 62e666400dddf605b9b6d9a7ac2918711b5c5629 (diff) | |
download | postgresql-bd56e74127dea4102d1fc761d65fefbb32146713.tar.gz postgresql-bd56e74127dea4102d1fc761d65fefbb32146713.zip |
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.sgml | 6 | ||||
-rw-r--r-- | src/backend/replication/walreceiver.c | 42 | ||||
-rw-r--r-- | src/backend/replication/walsender.c | 5 |
3 files changed, 39 insertions, 14 deletions
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index 1a750593707..d32626677d1 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -1682,8 +1682,10 @@ The commands accepted in walsender mode are: </term> <listitem> <para> - The standby's current xmin. This may be 0, if the standby does not - support feedback, or is not yet in Hot Standby state. + 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 73592973ac6..37d5e0821ed 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -47,6 +47,7 @@ #include <unistd.h> #include "access/timeline.h" +#include "access/transam.h" #include "access/xlog_internal.h" #include "libpq/pqformat.h" #include "libpq/pqsignal.h" @@ -138,7 +139,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(bool force, bool requestReply); -static void XLogWalRcvSendHSFeedback(void); +static void XLogWalRcvSendHSFeedback(bool immed); static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime); /* Signal handlers */ @@ -406,6 +407,7 @@ WalReceiverMain(void) { got_SIGHUP = false; ProcessConfigFile(PGC_SIGHUP); + XLogWalRcvSendHSFeedback(true); } /* Wait a while for data to arrive */ @@ -496,7 +498,7 @@ WalReceiverMain(void) } XLogWalRcvSendReply(requestReply, requestReply); - XLogWalRcvSendHSFeedback(); + XLogWalRcvSendHSFeedback(false); } } @@ -1059,46 +1061,60 @@ XLogWalRcvSendReply(bool force, bool requestReply) /* * 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) { 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(sendTime, now, + if (!immed) + { + /* + * Send feedback at most once per wal_receiver_status_interval. + */ + if (!TimestampDifferenceExceeds(sendTime, now, wal_receiver_status_interval * 1000)) - return; - sendTime = now; + 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 @@ -1118,6 +1134,10 @@ XLogWalRcvSendHSFeedback(void) pq_sendint(&reply_message, xmin, 4); pq_sendint(&reply_message, nextEpoch, 4); walrcv_send(reply_message.data, reply_message.len); + 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 10e40506965..490b121362f 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -870,9 +870,12 @@ ProcessStandbyHSFeedbackMessage(void) feedbackXmin, feedbackEpoch); - /* Ignore invalid xmin (can't actually happen with current walreceiver) */ + /* Unset WalSender's xmin if the feedback message value is invalid */ if (!TransactionIdIsNormal(feedbackXmin)) + { + MyPgXact->xmin = InvalidTransactionId; return; + } /* * Check that the provided xmin/epoch are sane, that is, not in the future |