aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlogutils.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2016-05-04 17:32:22 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2016-05-04 17:32:22 -0300
commitc1543a81a7a89207b6c45b8f3f7f07b1148fcc6e (patch)
tree4a19f5b8572e10fee45f184f4b977acbad393bca /src/backend/access/transam/xlogutils.c
parent6535bf399894db3597d257486062fe17311c642e (diff)
downloadpostgresql-c1543a81a7a89207b6c45b8f3f7f07b1148fcc6e.tar.gz
postgresql-c1543a81a7a89207b6c45b8f3f7f07b1148fcc6e.zip
Revert timeline following in replication slots
This reverts commits f07d18b6e94d, 82c83b337202, 3a3b309041b0, and 24c5f1a103ce. This feature has shown enough immaturity that it was deemed better to rip it out before rushing some more fixes at the last minute. There are discussions on larger changes in this area for the next release.
Diffstat (limited to 'src/backend/access/transam/xlogutils.c')
-rw-r--r--src/backend/access/transam/xlogutils.c212
1 files changed, 15 insertions, 197 deletions
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index f6ca2b95e51..cb4563ed731 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -19,7 +19,6 @@
#include <unistd.h>
-#include "access/timeline.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xlogutils.h"
@@ -660,7 +659,6 @@ XLogRead(char *buf, TimeLineID tli, XLogRecPtr startptr, Size count)
/* state maintained across calls */
static int sendFile = -1;
static XLogSegNo sendSegNo = 0;
- static TimeLineID sendTLI = 0;
static uint32 sendOff = 0;
p = buf;
@@ -676,8 +674,7 @@ XLogRead(char *buf, TimeLineID tli, XLogRecPtr startptr, Size count)
startoff = recptr % XLogSegSize;
/* Do we need to switch to a different xlog segment? */
- if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo) ||
- sendTLI != tli)
+ if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo))
{
char path[MAXPGPATH];
@@ -704,7 +701,6 @@ XLogRead(char *buf, TimeLineID tli, XLogRecPtr startptr, Size count)
path)));
}
sendOff = 0;
- sendTLI = tli;
}
/* Need to seek in the file? */
@@ -753,147 +749,6 @@ XLogRead(char *buf, TimeLineID tli, XLogRecPtr startptr, Size count)
}
/*
- * Determine XLogReaderState->currTLI and ->currTLIValidUntil;
- * XLogReaderState->EndRecPtr, ->currRecPtr and ThisTimeLineID affect the
- * decision. This may later be used to determine which xlog segment file to
- * open, etc.
- *
- * We switch to an xlog segment from the new timeline eagerly when on a
- * historical timeline, as soon as we reach the start of the xlog segment
- * containing the timeline switch. The server copied the segment to the new
- * timeline so all the data up to the switch point is the same, but there's no
- * guarantee the old segment will still exist. It may have been deleted or
- * renamed with a .partial suffix so we can't necessarily keep reading from
- * the old TLI even though tliSwitchPoint says it's OK.
- *
- * Because of this, callers MAY NOT assume that currTLI is the timeline that
- * will be in a page's xlp_tli; the page may begin on an older timeline or we
- * might be reading from historical timeline data on a segment that's been
- * copied to a new timeline.
- */
-static void
-XLogReadDetermineTimeline(XLogReaderState *state)
-{
- /* Read the history on first time through */
- if (state->timelineHistory == NIL)
- state->timelineHistory = readTimeLineHistory(ThisTimeLineID);
-
- /*
- * Are we reading the record immediately following the one we read last
- * time? If not, then don't use the cached timeline info.
- */
- if (state->currRecPtr != state->EndRecPtr)
- {
- state->currTLI = 0;
- state->currTLIValidUntil = InvalidXLogRecPtr;
- }
-
- /*
- * Are we reading a timeline that used to be the latest one, but became
- * historical? This can happen in a replica that gets promoted, and in a
- * cascading replica whose upstream gets promoted. In either case,
- * re-read the timeline history data. We cannot read past the timeline
- * switch point, because either the records in the old timeline might be
- * invalid, or worse, they may valid but *different* from the ones we
- * should be reading.
- */
- if (state->currTLIValidUntil == InvalidXLogRecPtr &&
- state->currTLI != ThisTimeLineID &&
- state->currTLI != 0)
- {
- /* re-read timeline history */
- list_free_deep(state->timelineHistory);
- state->timelineHistory = readTimeLineHistory(ThisTimeLineID);
-
- elog(DEBUG2, "timeline %u became historical during decoding",
- state->currTLI);
-
- /* then invalidate the cached timeline info */
- state->currTLI = 0;
- state->currTLIValidUntil = InvalidXLogRecPtr;
- }
-
- /*
- * Are we reading a record immediately following a timeline switch? If
- * so, we must follow the switch too.
- */
- if (state->currRecPtr == state->EndRecPtr &&
- state->currTLI != 0 &&
- state->currTLIValidUntil != InvalidXLogRecPtr &&
- state->currRecPtr >= state->currTLIValidUntil)
- {
- elog(DEBUG2,
- "requested record %X/%X is on segment containing end of timeline %u valid until %X/%X, switching to next timeline",
- (uint32) (state->currRecPtr >> 32),
- (uint32) state->currRecPtr,
- state->currTLI,
- (uint32) (state->currTLIValidUntil >> 32),
- (uint32) (state->currTLIValidUntil));
-
- /* invalidate TLI info so we look up the next TLI */
- state->currTLI = 0;
- state->currTLIValidUntil = InvalidXLogRecPtr;
- }
-
- if (state->currTLI == 0)
- {
- /*
- * Something changed; work out what timeline this record is on. We
- * might read it from the segment on this TLI or, if the segment is
- * also contained by newer timelines, the copy from a newer TLI.
- */
- state->currTLI = tliOfPointInHistory(state->currRecPtr,
- state->timelineHistory);
-
- /*
- * Look for the most recent timeline that's on the same xlog segment
- * as this record, since that's the only one we can assume is still
- * readable.
- */
- while (state->currTLI != ThisTimeLineID &&
- state->currTLIValidUntil == InvalidXLogRecPtr)
- {
- XLogRecPtr tliSwitch;
- TimeLineID nextTLI;
-
- CHECK_FOR_INTERRUPTS();
-
- tliSwitch = tliSwitchPoint(state->currTLI, state->timelineHistory,
- &nextTLI);
-
- /* round ValidUntil down to start of seg containing the switch */
- state->currTLIValidUntil =
- ((tliSwitch / XLogSegSize) * XLogSegSize);
-
- if (state->currRecPtr >= state->currTLIValidUntil)
- {
- /*
- * The new currTLI ends on this WAL segment so check the next
- * TLI to see if it's the last one on the segment.
- *
- * If that's the current TLI we'll stop searching.
- */
- state->currTLI = nextTLI;
- state->currTLIValidUntil = InvalidXLogRecPtr;
- }
- }
-
- /*
- * We're now either reading from the first xlog segment in the current
- * server's timeline or the most recent historical timeline that
- * exists on the target segment.
- */
- elog(DEBUG2, "XLog read ptr %X/%X is on segment with TLI %u valid until %X/%X, server current TLI is %u",
- (uint32) (state->currRecPtr >> 32),
- (uint32) state->currRecPtr,
- state->currTLI,
- (uint32) (state->currTLIValidUntil >> 32),
- (uint32) (state->currTLIValidUntil),
- ThisTimeLineID);
- }
-}
-
-/*
* read_page callback for reading local xlog files
*
* Public because it would likely be very helpful for someone writing another
@@ -914,65 +769,28 @@ read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr,
int count;
loc = targetPagePtr + reqLen;
-
- /* Make sure enough xlog is available... */
while (1)
{
/*
- * Check which timeline to get the record from.
- *
- * We have to do it each time through the loop because if we're in
- * recovery as a cascading standby, the current timeline might've
- * become historical.
+ * TODO: we're going to have to do something more intelligent about
+ * timelines on standbys. Use readTimeLineHistory() and
+ * tliOfPointInHistory() to get the proper LSN? For now we'll catch
+ * that case earlier, but the code and TODO is left in here for when
+ * that changes.
*/
- XLogReadDetermineTimeline(state);
-
- if (state->currTLI == ThisTimeLineID)
+ if (!RecoveryInProgress())
{
- /*
- * We're reading from the current timeline so we might have to
- * wait for the desired record to be generated (or, for a standby,
- * received & replayed)
- */
- if (!RecoveryInProgress())
- {
- *pageTLI = ThisTimeLineID;
- read_upto = GetFlushRecPtr();
- }
- else
- read_upto = GetXLogReplayRecPtr(pageTLI);
-
- if (loc <= read_upto)
- break;
-
- CHECK_FOR_INTERRUPTS();
- pg_usleep(1000L);
+ *pageTLI = ThisTimeLineID;
+ read_upto = GetFlushRecPtr();
}
else
- {
- /*
- * We're on a historical timeline, so limit reading to the switch
- * point where we moved to the next timeline.
- *
- * We don't need to GetFlushRecPtr or GetXLogReplayRecPtr. We know
- * about the new timeline, so we must've received past the end of
- * it.
- */
- read_upto = state->currTLIValidUntil;
-
- /*
- * Setting pageTLI to our wanted record's TLI is slightly wrong;
- * the page might begin on an older timeline if it contains a
- * timeline switch, since its xlog segment will have been copied
- * from the prior timeline. This is pretty harmless though, as
- * nothing cares so long as the timeline doesn't go backwards. We
- * should read the page header instead; FIXME someday.
- */
- *pageTLI = state->currTLI;
-
- /* No need to wait on a historical timeline */
+ read_upto = GetXLogReplayRecPtr(pageTLI);
+
+ if (loc <= read_upto)
break;
- }
+
+ CHECK_FOR_INTERRUPTS();
+ pg_usleep(1000L);
}
if (targetPagePtr + XLOG_BLCKSZ <= read_upto)