38
38
#include <signal.h>
39
39
#include <unistd.h>
40
40
41
+ #include "access/transam.h"
41
42
#include "access/xlog_internal.h"
42
43
#include "libpq/pqsignal.h"
43
44
#include "miscadmin.h"
@@ -123,7 +124,7 @@ static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
123
124
static void XLogWalRcvWrite (char * buf , Size nbytes , XLogRecPtr recptr );
124
125
static void XLogWalRcvFlush (bool dying );
125
126
static void XLogWalRcvSendReply (void );
126
- static void XLogWalRcvSendHSFeedback (void );
127
+ static void XLogWalRcvSendHSFeedback (bool immed );
127
128
static void ProcessWalSndrMessage (XLogRecPtr walEnd , TimestampTz sendTime );
128
129
129
130
/* Signal handlers */
@@ -312,6 +313,7 @@ WalReceiverMain(void)
312
313
{
313
314
got_SIGHUP = false;
314
315
ProcessConfigFile (PGC_SIGHUP );
316
+ XLogWalRcvSendHSFeedback (true);
315
317
}
316
318
317
319
/* Wait a while for data to arrive */
@@ -340,7 +342,7 @@ WalReceiverMain(void)
340
342
* master anyway, to report any progress in applying WAL.
341
343
*/
342
344
XLogWalRcvSendReply ();
343
- XLogWalRcvSendHSFeedback ();
345
+ XLogWalRcvSendHSFeedback (false );
344
346
}
345
347
}
346
348
}
@@ -621,7 +623,7 @@ XLogWalRcvFlush(bool dying)
621
623
if (!dying )
622
624
{
623
625
XLogWalRcvSendReply ();
624
- XLogWalRcvSendHSFeedback ();
626
+ XLogWalRcvSendHSFeedback (false );
625
627
}
626
628
}
627
629
}
@@ -681,45 +683,62 @@ XLogWalRcvSendReply(void)
681
683
/*
682
684
* Send hot standby feedback message to primary, plus the current time,
683
685
* 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.
684
689
*/
685
690
static void
686
- XLogWalRcvSendHSFeedback (void )
691
+ XLogWalRcvSendHSFeedback (bool immed )
687
692
{
688
693
char buf [sizeof (StandbyHSFeedbackMessage ) + 1 ];
689
694
TimestampTz now ;
690
695
TransactionId nextXid ;
691
696
uint32 nextEpoch ;
692
697
TransactionId xmin ;
698
+ static TimestampTz sendTime = 0 ;
699
+ static bool master_has_standby_xmin = false;
693
700
694
701
/*
695
702
* If the user doesn't want status to be reported to the master, be sure
696
703
* to exit before doing anything at all.
697
704
*/
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 )
699
707
return ;
700
708
701
709
/* Get current timestamp. */
702
710
now = GetCurrentTimestamp ();
703
711
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 ,
708
718
wal_receiver_status_interval * 1000 ))
709
- return ;
719
+ return ;
720
+ }
721
+
722
+ sendTime = now ;
710
723
711
724
/*
712
725
* If Hot Standby is not yet active there is nothing to send. Check this
713
726
* after the interval has expired to reduce number of calls.
714
727
*/
715
728
if (!HotStandbyActive ())
729
+ {
730
+ Assert (!master_has_standby_xmin );
716
731
return ;
732
+ }
717
733
718
734
/*
719
735
* Make the expensive call to get the oldest xmin once we are certain
720
736
* everything else has been checked.
721
737
*/
722
- xmin = GetOldestXmin (true, false);
738
+ if (hot_standby_feedback )
739
+ xmin = GetOldestXmin (true, false);
740
+ else
741
+ xmin = InvalidTransactionId ;
723
742
724
743
/*
725
744
* Get epoch and adjust if nextXid and oldestXmin are different sides of
@@ -744,6 +763,10 @@ XLogWalRcvSendHSFeedback(void)
744
763
buf [0 ] = 'h' ;
745
764
memcpy (& buf [1 ], & feedback_message , sizeof (StandbyHSFeedbackMessage ));
746
765
walrcv_send (buf , sizeof (StandbyHSFeedbackMessage ) + 1 );
766
+ if (TransactionIdIsValid (xmin ))
767
+ master_has_standby_xmin = true;
768
+ else
769
+ master_has_standby_xmin = false;
747
770
}
748
771
749
772
/*
0 commit comments