aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index c10dc889c61..7c40b1a5111 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -3692,11 +3692,36 @@ XLogFileReadAnyTLI(XLogSegNo segno, int emode, int source)
foreach(cell, tles)
{
- TimeLineID tli = ((TimeLineHistoryEntry *) lfirst(cell))->tli;
+ TimeLineHistoryEntry *hent = (TimeLineHistoryEntry *) lfirst(cell);
+ TimeLineID tli = hent->tli;
if (tli < curFileTLI)
break; /* don't bother looking at too-old TLIs */
+ /*
+ * Skip scanning the timeline ID that the logfile segment to read
+ * doesn't belong to
+ */
+ if (hent->begin != InvalidXLogRecPtr)
+ {
+ XLogSegNo beginseg = 0;
+
+ XLByteToSeg(hent->begin, beginseg);
+
+ /*
+ * The logfile segment that doesn't belong to the timeline is
+ * older or newer than the segment that the timeline started or
+ * ended at, respectively. It's sufficient to check only the
+ * starting segment of the timeline here. Since the timelines are
+ * scanned in descending order in this loop, any segments newer
+ * than the ending segment should belong to newer timeline and
+ * have already been read before. So it's not necessary to check
+ * the ending segment of the timeline here.
+ */
+ if (segno < beginseg)
+ continue;
+ }
+
if (source == XLOG_FROM_ANY || source == XLOG_FROM_ARCHIVE)
{
fd = XLogFileRead(segno, emode, tli,