@@ -124,7 +124,7 @@ static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
124
124
static void XLogWalRcvWrite (char * buf , Size nbytes , XLogRecPtr recptr );
125
125
static void XLogWalRcvFlush (bool dying );
126
126
static void XLogWalRcvSendReply (void );
127
- static void XLogWalRcvSendHSFeedback (void );
127
+ static void XLogWalRcvSendHSFeedback (bool immed );
128
128
129
129
/* Signal handlers */
130
130
static void WalRcvSigHupHandler (SIGNAL_ARGS );
@@ -310,6 +310,7 @@ WalReceiverMain(void)
310
310
{
311
311
got_SIGHUP = false;
312
312
ProcessConfigFile (PGC_SIGHUP );
313
+ XLogWalRcvSendHSFeedback (true);
313
314
}
314
315
315
316
/* Wait a while for data to arrive */
@@ -338,7 +339,7 @@ WalReceiverMain(void)
338
339
* master anyway, to report any progress in applying WAL.
339
340
*/
340
341
XLogWalRcvSendReply ();
341
- XLogWalRcvSendHSFeedback ();
342
+ XLogWalRcvSendHSFeedback (false );
342
343
}
343
344
}
344
345
}
@@ -591,7 +592,7 @@ XLogWalRcvFlush(bool dying)
591
592
if (!dying )
592
593
{
593
594
XLogWalRcvSendReply ();
594
- XLogWalRcvSendHSFeedback ();
595
+ XLogWalRcvSendHSFeedback (false );
595
596
}
596
597
}
597
598
}
@@ -651,45 +652,62 @@ XLogWalRcvSendReply(void)
651
652
/*
652
653
* Send hot standby feedback message to primary, plus the current time,
653
654
* in case they don't have a watch.
655
+ *
656
+ * If the user disables feedback, send one final message to tell sender
657
+ * to forget about the xmin on this standby.
654
658
*/
655
659
static void
656
- XLogWalRcvSendHSFeedback (void )
660
+ XLogWalRcvSendHSFeedback (bool immed )
657
661
{
658
662
char buf [sizeof (StandbyHSFeedbackMessage ) + 1 ];
659
663
TimestampTz now ;
660
664
TransactionId nextXid ;
661
665
uint32 nextEpoch ;
662
666
TransactionId xmin ;
667
+ static TimestampTz sendTime = 0 ;
668
+ static bool master_has_standby_xmin = false;
663
669
664
670
/*
665
671
* If the user doesn't want status to be reported to the master, be sure
666
672
* to exit before doing anything at all.
667
673
*/
668
- if (wal_receiver_status_interval <= 0 || !hot_standby_feedback )
674
+ if ((wal_receiver_status_interval <= 0 || !hot_standby_feedback ) &&
675
+ !master_has_standby_xmin )
669
676
return ;
670
677
671
678
/* Get current timestamp. */
672
679
now = GetCurrentTimestamp ();
673
680
674
- /*
675
- * Send feedback at most once per wal_receiver_status_interval.
676
- */
677
- if (!TimestampDifferenceExceeds (feedback_message .sendTime , now ,
681
+ if (!immed )
682
+ {
683
+ /*
684
+ * Send feedback at most once per wal_receiver_status_interval.
685
+ */
686
+ if (!TimestampDifferenceExceeds (sendTime , now ,
678
687
wal_receiver_status_interval * 1000 ))
679
- return ;
688
+ return ;
689
+ }
690
+
691
+ sendTime = now ;
680
692
681
693
/*
682
694
* If Hot Standby is not yet active there is nothing to send. Check this
683
695
* after the interval has expired to reduce number of calls.
684
696
*/
685
697
if (!HotStandbyActive ())
698
+ {
699
+ Assert (!master_has_standby_xmin );
686
700
return ;
701
+ }
687
702
688
703
/*
689
704
* Make the expensive call to get the oldest xmin once we are certain
690
705
* everything else has been checked.
691
706
*/
692
- xmin = GetOldestXmin (true, false);
707
+ if (hot_standby_feedback )
708
+ xmin = GetOldestXmin (true, false);
709
+ else
710
+ xmin = InvalidTransactionId ;
693
711
694
712
/*
695
713
* Get epoch and adjust if nextXid and oldestXmin are different sides of
@@ -714,4 +732,8 @@ XLogWalRcvSendHSFeedback(void)
714
732
buf [0 ] = 'h' ;
715
733
memcpy (& buf [1 ], & feedback_message , sizeof (StandbyHSFeedbackMessage ));
716
734
walrcv_send (buf , sizeof (StandbyHSFeedbackMessage ) + 1 );
735
+ if (TransactionIdIsValid (xmin ))
736
+ master_has_standby_xmin = true;
737
+ else
738
+ master_has_standby_xmin = false;
717
739
}
0 commit comments