aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlogreader.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-01-17 19:05:19 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-01-17 19:27:04 +0200
commit1296d5c53cad26c775993d6c29e1311919202638 (patch)
tree4e49b02886034e3d3a4a158e6334cce5453814ba /src/backend/access/transam/xlogreader.c
parentb14f81bc9a65993129e93052634e358b310b8554 (diff)
downloadpostgresql-1296d5c53cad26c775993d6c29e1311919202638.tar.gz
postgresql-1296d5c53cad26c775993d6c29e1311919202638.zip
Fix a couple of error-handling bugs in the xlogreader patch.
XLogReadRecord should reset its state on every error, to make sure it re-reads the page on next call. It was inconsistent in that some errors did that, but some did not. In ReadRecord(), don't give up on an error if we're in standby mode. The loop was set up to retry, but the checks within the loop broke out of the loop on any error. Andres Freund, with some tweaking by me.
Diffstat (limited to 'src/backend/access/transam/xlogreader.c')
-rw-r--r--src/backend/access/transam/xlogreader.c30
1 files changed, 7 insertions, 23 deletions
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index ff871a3412f..75164f686e5 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -222,11 +222,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
readOff = ReadPageInternal(state, targetPagePtr, SizeOfXLogRecord);
if (readOff < 0)
- {
- if (state->errormsg_buf[0] != '\0')
- *errormsg = state->errormsg_buf;
- return NULL;
- }
+ goto err;
/*
* ReadPageInternal always returns at least the page header, so we can
@@ -246,8 +242,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
{
report_invalid_record(state, "invalid record offset at %X/%X",
(uint32) (RecPtr >> 32), (uint32) RecPtr);
- *errormsg = state->errormsg_buf;
- return NULL;
+ goto err;
}
if ((((XLogPageHeader) state->readBuf)->xlp_info & XLP_FIRST_IS_CONTRECORD) &&
@@ -255,8 +250,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
{
report_invalid_record(state, "contrecord is requested by %X/%X",
(uint32) (RecPtr >> 32), (uint32) RecPtr);
- *errormsg = state->errormsg_buf;
- return NULL;
+ goto err;
}
/* ReadPageInternal has verified the page header */
@@ -270,11 +264,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
targetPagePtr,
Min(targetRecOff + SizeOfXLogRecord, XLOG_BLCKSZ));
if (readOff < 0)
- {
- if (state->errormsg_buf[0] != '\0')
- *errormsg = state->errormsg_buf;
- return NULL;
- }
+ goto err;
/*
* Read the record length.
@@ -300,11 +290,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
{
if (!ValidXLogRecordHeader(state, RecPtr, state->ReadRecPtr, record,
randAccess))
- {
- if (state->errormsg_buf[0] != '\0')
- *errormsg = state->errormsg_buf;
- return NULL;
- }
+ goto err;
gotheader = true;
}
else
@@ -314,8 +300,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
{
report_invalid_record(state, "invalid record length at %X/%X",
(uint32) (RecPtr >> 32), (uint32) RecPtr);
- *errormsg = state->errormsg_buf;
- return NULL;
+ goto err;
}
gotheader = false;
}
@@ -330,8 +315,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
report_invalid_record(state, "record length %u at %X/%X too long",
total_len,
(uint32) (RecPtr >> 32), (uint32) RecPtr);
- *errormsg = state->errormsg_buf;
- return NULL;
+ goto err;
}
len = XLOG_BLCKSZ - RecPtr % XLOG_BLCKSZ;