From 1b9211740175b7f9cb6810c822a67d4065ca9cf0 Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi Date: Wed, 29 Jan 2020 11:17:56 +0900 Subject: [PATCH v1] Don't try fetching out-of-timeline segments. XLogFileReadAnyTLI scans known TLIs down from the largest one in descending order while searching the target segment. Even if we know that the segment belongs to a lower TLI, it tries opening the segment of the larger TLIs just to fail. Under certain circumstances that access to non-existent files take a long time and makes recovery time significantly longer. Although a segment beyond the end of a TLI suggests that the XLOG/archive files may be broken, we can safely ignore such files as far as recovery proceeds. --- src/backend/access/transam/xlog.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 6e09ded597..415288f50d 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -3738,11 +3738,27 @@ 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 segments not belonging to the TLI */ + if (hent->begin != InvalidXLogRecPtr) + { + XLogSegNo beginseg = 0; + + XLByteToSeg(hent->begin, beginseg, wal_segment_size); + + /* + * We are scanning TLIs in descending order. It is sufficient to + * check only the upper boundary. + */ + if (segno < beginseg) + continue; /* don't bother looking at future TLIs */ + } + if (source == XLOG_FROM_ANY || source == XLOG_FROM_ARCHIVE) { fd = XLogFileRead(segno, emode, tli, -- 2.18.2