mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
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.
This commit is contained in:
parent
f18858dc72
commit
2dde11a632
@ -1617,7 +1617,10 @@ The commands accepted in walsender mode are:
|
|||||||
</term>
|
</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The standby's current xmin.
|
The standby's current xmin. This may be 0, if the standby is
|
||||||
|
sending notification that Hot Standby feedback will no
|
||||||
|
longer be sent on this connection. Later non-zero messages may
|
||||||
|
reinitiate the feedback mechanism.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "access/transam.h"
|
||||||
#include "access/xlog_internal.h"
|
#include "access/xlog_internal.h"
|
||||||
#include "libpq/pqsignal.h"
|
#include "libpq/pqsignal.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
@ -123,7 +124,7 @@ static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
|
|||||||
static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
|
static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
|
||||||
static void XLogWalRcvFlush(bool dying);
|
static void XLogWalRcvFlush(bool dying);
|
||||||
static void XLogWalRcvSendReply(void);
|
static void XLogWalRcvSendReply(void);
|
||||||
static void XLogWalRcvSendHSFeedback(void);
|
static void XLogWalRcvSendHSFeedback(bool immed);
|
||||||
static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime);
|
static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime);
|
||||||
|
|
||||||
/* Signal handlers */
|
/* Signal handlers */
|
||||||
@ -312,6 +313,7 @@ WalReceiverMain(void)
|
|||||||
{
|
{
|
||||||
got_SIGHUP = false;
|
got_SIGHUP = false;
|
||||||
ProcessConfigFile(PGC_SIGHUP);
|
ProcessConfigFile(PGC_SIGHUP);
|
||||||
|
XLogWalRcvSendHSFeedback(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait a while for data to arrive */
|
/* Wait a while for data to arrive */
|
||||||
@ -340,7 +342,7 @@ WalReceiverMain(void)
|
|||||||
* master anyway, to report any progress in applying WAL.
|
* master anyway, to report any progress in applying WAL.
|
||||||
*/
|
*/
|
||||||
XLogWalRcvSendReply();
|
XLogWalRcvSendReply();
|
||||||
XLogWalRcvSendHSFeedback();
|
XLogWalRcvSendHSFeedback(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,7 +623,7 @@ XLogWalRcvFlush(bool dying)
|
|||||||
if (!dying)
|
if (!dying)
|
||||||
{
|
{
|
||||||
XLogWalRcvSendReply();
|
XLogWalRcvSendReply();
|
||||||
XLogWalRcvSendHSFeedback();
|
XLogWalRcvSendHSFeedback(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,45 +683,62 @@ XLogWalRcvSendReply(void)
|
|||||||
/*
|
/*
|
||||||
* Send hot standby feedback message to primary, plus the current time,
|
* Send hot standby feedback message to primary, plus the current time,
|
||||||
* in case they don't have a watch.
|
* in case they don't have a watch.
|
||||||
|
*
|
||||||
|
* If the user disables feedback, send one final message to tell sender
|
||||||
|
* to forget about the xmin on this standby.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
XLogWalRcvSendHSFeedback(void)
|
XLogWalRcvSendHSFeedback(bool immed)
|
||||||
{
|
{
|
||||||
char buf[sizeof(StandbyHSFeedbackMessage) + 1];
|
char buf[sizeof(StandbyHSFeedbackMessage) + 1];
|
||||||
TimestampTz now;
|
TimestampTz now;
|
||||||
TransactionId nextXid;
|
TransactionId nextXid;
|
||||||
uint32 nextEpoch;
|
uint32 nextEpoch;
|
||||||
TransactionId xmin;
|
TransactionId xmin;
|
||||||
|
static TimestampTz sendTime = 0;
|
||||||
|
static bool master_has_standby_xmin = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the user doesn't want status to be reported to the master, be sure
|
* If the user doesn't want status to be reported to the master, be sure
|
||||||
* to exit before doing anything at all.
|
* to exit before doing anything at all.
|
||||||
*/
|
*/
|
||||||
if (wal_receiver_status_interval <= 0 || !hot_standby_feedback)
|
if ((wal_receiver_status_interval <= 0 || !hot_standby_feedback) &&
|
||||||
|
!master_has_standby_xmin)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Get current timestamp. */
|
/* Get current timestamp. */
|
||||||
now = GetCurrentTimestamp();
|
now = GetCurrentTimestamp();
|
||||||
|
|
||||||
|
if (!immed)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Send feedback at most once per wal_receiver_status_interval.
|
* Send feedback at most once per wal_receiver_status_interval.
|
||||||
*/
|
*/
|
||||||
if (!TimestampDifferenceExceeds(feedback_message.sendTime, now,
|
if (!TimestampDifferenceExceeds(sendTime, now,
|
||||||
wal_receiver_status_interval * 1000))
|
wal_receiver_status_interval * 1000))
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendTime = now;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If Hot Standby is not yet active there is nothing to send. Check this
|
* If Hot Standby is not yet active there is nothing to send. Check this
|
||||||
* after the interval has expired to reduce number of calls.
|
* after the interval has expired to reduce number of calls.
|
||||||
*/
|
*/
|
||||||
if (!HotStandbyActive())
|
if (!HotStandbyActive())
|
||||||
|
{
|
||||||
|
Assert(!master_has_standby_xmin);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make the expensive call to get the oldest xmin once we are certain
|
* Make the expensive call to get the oldest xmin once we are certain
|
||||||
* everything else has been checked.
|
* everything else has been checked.
|
||||||
*/
|
*/
|
||||||
|
if (hot_standby_feedback)
|
||||||
xmin = GetOldestXmin(true, false);
|
xmin = GetOldestXmin(true, false);
|
||||||
|
else
|
||||||
|
xmin = InvalidTransactionId;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get epoch and adjust if nextXid and oldestXmin are different sides of
|
* Get epoch and adjust if nextXid and oldestXmin are different sides of
|
||||||
@ -744,6 +763,10 @@ XLogWalRcvSendHSFeedback(void)
|
|||||||
buf[0] = 'h';
|
buf[0] = 'h';
|
||||||
memcpy(&buf[1], &feedback_message, sizeof(StandbyHSFeedbackMessage));
|
memcpy(&buf[1], &feedback_message, sizeof(StandbyHSFeedbackMessage));
|
||||||
walrcv_send(buf, sizeof(StandbyHSFeedbackMessage) + 1);
|
walrcv_send(buf, sizeof(StandbyHSFeedbackMessage) + 1);
|
||||||
|
if (TransactionIdIsValid(xmin))
|
||||||
|
master_has_standby_xmin = true;
|
||||||
|
else
|
||||||
|
master_has_standby_xmin = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -656,9 +656,12 @@ ProcessStandbyHSFeedbackMessage(void)
|
|||||||
reply.xmin,
|
reply.xmin,
|
||||||
reply.epoch);
|
reply.epoch);
|
||||||
|
|
||||||
/* Ignore invalid xmin (can't actually happen with current walreceiver) */
|
/* Unset WalSender's xmin if the feedback message value is invalid */
|
||||||
if (!TransactionIdIsNormal(reply.xmin))
|
if (!TransactionIdIsNormal(reply.xmin))
|
||||||
|
{
|
||||||
|
MyPgXact->xmin = InvalidTransactionId;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the provided xmin/epoch are sane, that is, not in the future
|
* Check that the provided xmin/epoch are sane, that is, not in the future
|
||||||
|
Loading…
x
Reference in New Issue
Block a user