diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-01-17 19:05:19 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-01-17 19:27:04 +0200 |
commit | 1296d5c53cad26c775993d6c29e1311919202638 (patch) | |
tree | 4e49b02886034e3d3a4a158e6334cce5453814ba /src/backend/access/transam/xlogreader.c | |
parent | b14f81bc9a65993129e93052634e358b310b8554 (diff) | |
download | postgresql-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.c | 30 |
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; |