Skip to content

Commit bd56e74

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 62e6664 commit bd56e74

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
lines changed

doc/src/sgml/protocol.sgml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,8 +1682,10 @@ The commands accepted in walsender mode are:
16821682
</term>
16831683
<listitem>
16841684
<para>
1685-
The standby's current xmin. This may be 0, if the standby does not
1686-
support feedback, or is not yet in Hot Standby state.
1685+
The standby's current xmin. This may be 0, if the standby is
1686+
sending notification that Hot Standby feedback will no longer
1687+
be sent on this connection. Later non-zero messages may
1688+
reinitiate the feedback mechanism.
16871689
</para>
16881690
</listitem>
16891691
</varlistentry>

src/backend/replication/walreceiver.c

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <unistd.h>
4848

4949
#include "access/timeline.h"
50+
#include "access/transam.h"
5051
#include "access/xlog_internal.h"
5152
#include "libpq/pqformat.h"
5253
#include "libpq/pqsignal.h"
@@ -138,7 +139,7 @@ static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
138139
static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
139140
static void XLogWalRcvFlush(bool dying);
140141
static void XLogWalRcvSendReply(bool force, bool requestReply);
141-
static void XLogWalRcvSendHSFeedback(void);
142+
static void XLogWalRcvSendHSFeedback(bool immed);
142143
static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime);
143144

144145
/* Signal handlers */
@@ -406,6 +407,7 @@ WalReceiverMain(void)
406407
{
407408
got_SIGHUP = false;
408409
ProcessConfigFile(PGC_SIGHUP);
410+
XLogWalRcvSendHSFeedback(true);
409411
}
410412

411413
/* Wait a while for data to arrive */
@@ -496,7 +498,7 @@ WalReceiverMain(void)
496498
}
497499

498500
XLogWalRcvSendReply(requestReply, requestReply);
499-
XLogWalRcvSendHSFeedback();
501+
XLogWalRcvSendHSFeedback(false);
500502
}
501503
}
502504

@@ -1059,46 +1061,60 @@ XLogWalRcvSendReply(bool force, bool requestReply)
10591061
/*
10601062
* Send hot standby feedback message to primary, plus the current time,
10611063
* in case they don't have a watch.
1064+
*
1065+
* If the user disables feedback, send one final message to tell sender
1066+
* to forget about the xmin on this standby.
10621067
*/
10631068
static void
1064-
XLogWalRcvSendHSFeedback(void)
1069+
XLogWalRcvSendHSFeedback(bool immed)
10651070
{
10661071
TimestampTz now;
10671072
TransactionId nextXid;
10681073
uint32 nextEpoch;
10691074
TransactionId xmin;
10701075
static TimestampTz sendTime = 0;
1076+
static bool master_has_standby_xmin = false;
10711077

10721078
/*
10731079
* If the user doesn't want status to be reported to the master, be sure
10741080
* to exit before doing anything at all.
10751081
*/
1076-
if (wal_receiver_status_interval <= 0 || !hot_standby_feedback)
1082+
if ((wal_receiver_status_interval <= 0 || !hot_standby_feedback) &&
1083+
!master_has_standby_xmin)
10771084
return;
10781085

10791086
/* Get current timestamp. */
10801087
now = GetCurrentTimestamp();
10811088

1082-
/*
1083-
* Send feedback at most once per wal_receiver_status_interval.
1084-
*/
1085-
if (!TimestampDifferenceExceeds(sendTime, now,
1089+
if (!immed)
1090+
{
1091+
/*
1092+
* Send feedback at most once per wal_receiver_status_interval.
1093+
*/
1094+
if (!TimestampDifferenceExceeds(sendTime, now,
10861095
wal_receiver_status_interval * 1000))
1087-
return;
1088-
sendTime = now;
1096+
return;
1097+
sendTime = now;
1098+
}
10891099

10901100
/*
10911101
* If Hot Standby is not yet active there is nothing to send. Check this
10921102
* after the interval has expired to reduce number of calls.
10931103
*/
10941104
if (!HotStandbyActive())
1105+
{
1106+
Assert(!master_has_standby_xmin);
10951107
return;
1108+
}
10961109

10971110
/*
10981111
* Make the expensive call to get the oldest xmin once we are certain
10991112
* everything else has been checked.
11001113
*/
1101-
xmin = GetOldestXmin(true, false);
1114+
if (hot_standby_feedback)
1115+
xmin = GetOldestXmin(true, false);
1116+
else
1117+
xmin = InvalidTransactionId;
11021118

11031119
/*
11041120
* Get epoch and adjust if nextXid and oldestXmin are different sides of
@@ -1118,6 +1134,10 @@ XLogWalRcvSendHSFeedback(void)
11181134
pq_sendint(&reply_message, xmin, 4);
11191135
pq_sendint(&reply_message, nextEpoch, 4);
11201136
walrcv_send(reply_message.data, reply_message.len);
1137+
if (TransactionIdIsValid(xmin))
1138+
master_has_standby_xmin = true;
1139+
else
1140+
master_has_standby_xmin = false;
11211141
}
11221142

11231143
/*

src/backend/replication/walsender.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,9 +870,12 @@ ProcessStandbyHSFeedbackMessage(void)
870870
feedbackXmin,
871871
feedbackEpoch);
872872

873-
/* Ignore invalid xmin (can't actually happen with current walreceiver) */
873+
/* Unset WalSender's xmin if the feedback message value is invalid */
874874
if (!TransactionIdIsNormal(feedbackXmin))
875+
{
876+
MyPgXact->xmin = InvalidTransactionId;
875877
return;
878+
}
876879

877880
/*
878881
* 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