aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlogreader.c24
-rw-r--r--src/backend/access/transam/xlogrecovery.c10
-rw-r--r--src/include/access/xlogreader.h3
3 files changed, 31 insertions, 6 deletions
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index cf5db23cb86..02d4414bac7 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -987,6 +987,13 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
return state->readLen;
/*
+ * Invalidate contents of internal buffer before read attempt. Just set
+ * the length to 0, rather than a full XLogReaderInvalReadState(), so we
+ * don't forget the segment we last successfully read.
+ */
+ state->readLen = 0;
+
+ /*
* Data is not in our buffer.
*
* Every time we actually read the segment, even if we looked at parts of
@@ -1066,11 +1073,8 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
return readLen;
err:
- if (state->errormsg_buf[0] != '\0')
- {
- state->errormsg_deferred = true;
- XLogReaderInvalReadState(state);
- }
+ XLogReaderInvalReadState(state);
+
return XLREAD_FAIL;
}
@@ -1323,6 +1327,16 @@ XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr,
}
/*
+ * Forget about an error produced by XLogReaderValidatePageHeader().
+ */
+void
+XLogReaderResetError(XLogReaderState *state)
+{
+ state->errormsg_buf[0] = '\0';
+ state->errormsg_deferred = false;
+}
+
+/*
* Find the first record with an lsn >= RecPtr.
*
* This is different from XLogBeginRead() in that RecPtr doesn't need to point
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index f6f894b36d1..f4aeda771c0 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -3339,13 +3339,21 @@ retry:
(errmsg_internal("%s", xlogreader->errormsg_buf)));
/* reset any error XLogReaderValidatePageHeader() might have set */
- xlogreader->errormsg_buf[0] = '\0';
+ XLogReaderResetError(xlogreader);
goto next_record_is_invalid;
}
return readLen;
next_record_is_invalid:
+
+ /*
+ * If we're reading ahead, give up fast. Retries and error reporting will
+ * be handled by a later read when recovery catches up to this point.
+ */
+ if (xlogreader->nonblocking)
+ return XLREAD_WOULDBLOCK;
+
lastSourceFailed = true;
if (readFile >= 0)
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index e73ea4a8408..6b851693b16 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -373,6 +373,9 @@ extern DecodedXLogRecord *XLogReadAhead(XLogReaderState *state,
extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
XLogRecPtr recptr, char *phdr);
+/* Forget error produced by XLogReaderValidatePageHeader(). */
+extern void XLogReaderResetError(XLogReaderState *state);
+
/*
* Error information from WALRead that both backend and frontend caller can
* process. Currently only errors from pg_pread can be reported.