Skip to content

Commit 8ebf5f7

Browse files
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.
1 parent bfb4704 commit 8ebf5f7

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed

doc/src/sgml/protocol.sgml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,10 @@ The commands accepted in walsender mode are:
15841584
</term>
15851585
<listitem>
15861586
<para>
1587-
The standby's current xmin.
1587+
The standby's current xmin. This may be 0, if the standby is
1588+
sending notification that Hot Standby feedback will no
1589+
longer be sent on this connection. Later non-zero messages may
1590+
reinitiate the feedback mechanism.
15881591
</para>
15891592
</listitem>
15901593
</varlistentry>

src/backend/replication/walreceiver.c

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
124124
static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
125125
static void XLogWalRcvFlush(bool dying);
126126
static void XLogWalRcvSendReply(void);
127-
static void XLogWalRcvSendHSFeedback(void);
127+
static void XLogWalRcvSendHSFeedback(bool immed);
128128

129129
/* Signal handlers */
130130
static void WalRcvSigHupHandler(SIGNAL_ARGS);
@@ -310,6 +310,7 @@ WalReceiverMain(void)
310310
{
311311
got_SIGHUP = false;
312312
ProcessConfigFile(PGC_SIGHUP);
313+
XLogWalRcvSendHSFeedback(true);
313314
}
314315

315316
/* Wait a while for data to arrive */
@@ -338,7 +339,7 @@ WalReceiverMain(void)
338339
* master anyway, to report any progress in applying WAL.
339340
*/
340341
XLogWalRcvSendReply();
341-
XLogWalRcvSendHSFeedback();
342+
XLogWalRcvSendHSFeedback(false);
342343
}
343344
}
344345
}
@@ -591,7 +592,7 @@ XLogWalRcvFlush(bool dying)
591592
if (!dying)
592593
{
593594
XLogWalRcvSendReply();
594-
XLogWalRcvSendHSFeedback();
595+
XLogWalRcvSendHSFeedback(false);
595596
}
596597
}
597598
}
@@ -651,45 +652,62 @@ XLogWalRcvSendReply(void)
651652
/*
652653
* Send hot standby feedback message to primary, plus the current time,
653654
* 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.
654658
*/
655659
static void
656-
XLogWalRcvSendHSFeedback(void)
660+
XLogWalRcvSendHSFeedback(bool immed)
657661
{
658662
char buf[sizeof(StandbyHSFeedbackMessage) + 1];
659663
TimestampTz now;
660664
TransactionId nextXid;
661665
uint32 nextEpoch;
662666
TransactionId xmin;
667+
static TimestampTz sendTime = 0;
668+
static bool master_has_standby_xmin = false;
663669

664670
/*
665671
* If the user doesn't want status to be reported to the master, be sure
666672
* to exit before doing anything at all.
667673
*/
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)
669676
return;
670677

671678
/* Get current timestamp. */
672679
now = GetCurrentTimestamp();
673680

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,
678687
wal_receiver_status_interval * 1000))
679-
return;
688+
return;
689+
}
690+
691+
sendTime = now;
680692

681693
/*
682694
* If Hot Standby is not yet active there is nothing to send. Check this
683695
* after the interval has expired to reduce number of calls.
684696
*/
685697
if (!HotStandbyActive())
698+
{
699+
Assert(!master_has_standby_xmin);
686700
return;
701+
}
687702

688703
/*
689704
* Make the expensive call to get the oldest xmin once we are certain
690705
* everything else has been checked.
691706
*/
692-
xmin = GetOldestXmin(true, false);
707+
if (hot_standby_feedback)
708+
xmin = GetOldestXmin(true, false);
709+
else
710+
xmin = InvalidTransactionId;
693711

694712
/*
695713
* Get epoch and adjust if nextXid and oldestXmin are different sides of
@@ -714,4 +732,8 @@ XLogWalRcvSendHSFeedback(void)
714732
buf[0] = 'h';
715733
memcpy(&buf[1], &feedback_message, sizeof(StandbyHSFeedbackMessage));
716734
walrcv_send(buf, sizeof(StandbyHSFeedbackMessage) + 1);
735+
if (TransactionIdIsValid(xmin))
736+
master_has_standby_xmin = true;
737+
else
738+
master_has_standby_xmin = false;
717739
}

src/backend/replication/walsender.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,9 +623,12 @@ ProcessStandbyHSFeedbackMessage(void)
623623
reply.xmin,
624624
reply.epoch);
625625

626-
/* Ignore invalid xmin (can't actually happen with current walreceiver) */
626+
/* Unset WalSender's xmin if the feedback message value is invalid */
627627
if (!TransactionIdIsNormal(reply.xmin))
628+
{
629+
MyProc->xmin = InvalidTransactionId;
628630
return;
631+
}
629632

630633
/*
631634
* Check that the provided xmin/epoch are sane, that is, not in the future

0 commit comments

Comments
 (0)