Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+4-2
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

+31-11
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

+4-1
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)