1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-18 17:42:25 +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:
Simon Riggs
2014-07-15 14:40:23 +01:00
parent f18858dc72
commit 2dde11a632
3 changed files with 42 additions and 13 deletions

View File

@ -38,6 +38,7 @@
#include <signal.h>
#include <unistd.h>
#include "access/transam.h"
#include "access/xlog_internal.h"
#include "libpq/pqsignal.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 XLogWalRcvFlush(bool dying);
static void XLogWalRcvSendReply(void);
static void XLogWalRcvSendHSFeedback(void);
static void XLogWalRcvSendHSFeedback(bool immed);
static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime);
/* Signal handlers */
@ -312,6 +313,7 @@ WalReceiverMain(void)
{
got_SIGHUP = false;
ProcessConfigFile(PGC_SIGHUP);
XLogWalRcvSendHSFeedback(true);
}
/* Wait a while for data to arrive */
@ -340,7 +342,7 @@ WalReceiverMain(void)
* master anyway, to report any progress in applying WAL.
*/
XLogWalRcvSendReply();
XLogWalRcvSendHSFeedback();
XLogWalRcvSendHSFeedback(false);
}
}
}
@ -621,7 +623,7 @@ XLogWalRcvFlush(bool dying)
if (!dying)
{
XLogWalRcvSendReply();
XLogWalRcvSendHSFeedback();
XLogWalRcvSendHSFeedback(false);
}
}
}
@ -681,45 +683,62 @@ XLogWalRcvSendReply(void)
/*
* Send hot standby feedback message to primary, plus the current time,
* 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
XLogWalRcvSendHSFeedback(void)
XLogWalRcvSendHSFeedback(bool immed)
{
char buf[sizeof(StandbyHSFeedbackMessage) + 1];
TimestampTz now;
TransactionId nextXid;
uint32 nextEpoch;
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
* 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;
/* Get current timestamp. */
now = GetCurrentTimestamp();
/*
* Send feedback at most once per wal_receiver_status_interval.
*/
if (!TimestampDifferenceExceeds(feedback_message.sendTime, now,
if (!immed)
{
/*
* Send feedback at most once per wal_receiver_status_interval.
*/
if (!TimestampDifferenceExceeds(sendTime, now,
wal_receiver_status_interval * 1000))
return;
return;
}
sendTime = now;
/*
* If Hot Standby is not yet active there is nothing to send. Check this
* after the interval has expired to reduce number of calls.
*/
if (!HotStandbyActive())
{
Assert(!master_has_standby_xmin);
return;
}
/*
* Make the expensive call to get the oldest xmin once we are certain
* everything else has been checked.
*/
xmin = GetOldestXmin(true, false);
if (hot_standby_feedback)
xmin = GetOldestXmin(true, false);
else
xmin = InvalidTransactionId;
/*
* Get epoch and adjust if nextXid and oldestXmin are different sides of
@ -744,6 +763,10 @@ XLogWalRcvSendHSFeedback(void)
buf[0] = 'h';
memcpy(&buf[1], &feedback_message, sizeof(StandbyHSFeedbackMessage));
walrcv_send(buf, sizeof(StandbyHSFeedbackMessage) + 1);
if (TransactionIdIsValid(xmin))
master_has_standby_xmin = true;
else
master_has_standby_xmin = false;
}
/*

View File

@ -656,9 +656,12 @@ ProcessStandbyHSFeedbackMessage(void)
reply.xmin,
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))
{
MyPgXact->xmin = InvalidTransactionId;
return;
}
/*
* Check that the provided xmin/epoch are sane, that is, not in the future