3838#include <signal.h>
3939#include <unistd.h>
4040
41+ #include "access/transam.h"
4142#include "access/xlog_internal.h"
4243#include "libpq/pqsignal.h"
4344#include "miscadmin.h"
@@ -123,7 +124,7 @@ static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
123124static void XLogWalRcvWrite (char * buf ,Size nbytes ,XLogRecPtr recptr );
124125static void XLogWalRcvFlush (bool dying );
125126static void XLogWalRcvSendReply (void );
126- static void XLogWalRcvSendHSFeedback (void );
127+ static void XLogWalRcvSendHSFeedback (bool immed );
127128static void ProcessWalSndrMessage (XLogRecPtr walEnd ,TimestampTz sendTime );
128129
129130/* Signal handlers */
@@ -312,6 +313,7 @@ WalReceiverMain(void)
312313{
313314got_SIGHUP = false;
314315ProcessConfigFile (PGC_SIGHUP );
316+ XLogWalRcvSendHSFeedback (true);
315317}
316318
317319/* Wait a while for data to arrive */
@@ -340,7 +342,7 @@ WalReceiverMain(void)
340342 * master anyway, to report any progress in applying WAL.
341343 */
342344XLogWalRcvSendReply ();
343- XLogWalRcvSendHSFeedback ();
345+ XLogWalRcvSendHSFeedback (false );
344346}
345347}
346348}
@@ -621,7 +623,7 @@ XLogWalRcvFlush(bool dying)
621623if (!dying )
622624{
623625XLogWalRcvSendReply ();
624- XLogWalRcvSendHSFeedback ();
626+ XLogWalRcvSendHSFeedback (false );
625627}
626628}
627629}
@@ -681,45 +683,62 @@ XLogWalRcvSendReply(void)
681683/*
682684 * Send hot standby feedback message to primary, plus the current time,
683685 * in case they don't have a watch.
686+ *
687+ * If the user disables feedback, send one final message to tell sender
688+ * to forget about the xmin on this standby.
684689 */
685690static void
686- XLogWalRcvSendHSFeedback (void )
691+ XLogWalRcvSendHSFeedback (bool immed )
687692{
688693char buf [sizeof (StandbyHSFeedbackMessage )+ 1 ];
689694TimestampTz now ;
690695TransactionId nextXid ;
691696uint32 nextEpoch ;
692697TransactionId xmin ;
698+ static TimestampTz sendTime = 0 ;
699+ static bool master_has_standby_xmin = false;
693700
694701/*
695702 * If the user doesn't want status to be reported to the master, be sure
696703 * to exit before doing anything at all.
697704 */
698- if (wal_receiver_status_interval <=0 || !hot_standby_feedback )
705+ if ((wal_receiver_status_interval <=0 || !hot_standby_feedback )&&
706+ !master_has_standby_xmin )
699707return ;
700708
701709/* Get current timestamp. */
702710now = GetCurrentTimestamp ();
703711
704- /*
705- * Send feedback at most once per wal_receiver_status_interval.
706- */
707- if (!TimestampDifferenceExceeds (feedback_message .sendTime ,now ,
712+ if (!immed )
713+ {
714+ /*
715+ * Send feedback at most once per wal_receiver_status_interval.
716+ */
717+ if (!TimestampDifferenceExceeds (sendTime ,now ,
708718wal_receiver_status_interval * 1000 ))
709- return ;
719+ return ;
720+ }
721+
722+ sendTime = now ;
710723
711724/*
712725 * If Hot Standby is not yet active there is nothing to send. Check this
713726 * after the interval has expired to reduce number of calls.
714727 */
715728if (!HotStandbyActive ())
729+ {
730+ Assert (!master_has_standby_xmin );
716731return ;
732+ }
717733
718734/*
719735 * Make the expensive call to get the oldest xmin once we are certain
720736 * everything else has been checked.
721737 */
722- xmin = GetOldestXmin (true, false);
738+ if (hot_standby_feedback )
739+ xmin = GetOldestXmin (true, false);
740+ else
741+ xmin = InvalidTransactionId ;
723742
724743/*
725744 * Get epoch and adjust if nextXid and oldestXmin are different sides of
@@ -744,6 +763,10 @@ XLogWalRcvSendHSFeedback(void)
744763buf [0 ]= 'h' ;
745764memcpy (& buf [1 ],& feedback_message ,sizeof (StandbyHSFeedbackMessage ));
746765walrcv_send (buf ,sizeof (StandbyHSFeedbackMessage )+ 1 );
766+ if (TransactionIdIsValid (xmin ))
767+ master_has_standby_xmin = true;
768+ else
769+ master_has_standby_xmin = false;
747770}
748771
749772/*