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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy