On Tue, Sep 27, 2022 at 8:31 AM Kyotaro Horiguchi <horikyota....@gmail.com> wrote: > > If all error-emitting site knows the LSN, we don't need the context > message. But *I* would like that the additional message looks like > "while reading record at LSN %X/%X" or slightly shorter version of > it. Because the targetRecPtr is the beginning of the current reading > record, not the LSN for the segment and offset. It may point to past > segments.
I think we could just say "LSN %X/%X, offset %u", because the overall context whether it's being read or written is implicit with the other part of the message. Please see the attached v1 patch. -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com
From b19aa25a0d1f2ce85abe0c2081c0e7ede256e329 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Date: Thu, 29 Sep 2022 13:29:44 +0000 Subject: [PATCH v1] Add LSN along with offset to error messages reported for WAL file read/write/validate header failures --- src/backend/access/transam/xlog.c | 8 ++++++-- src/backend/access/transam/xlogreader.c | 16 +++++++++++----- src/backend/access/transam/xlogrecovery.c | 13 ++++++++----- src/backend/access/transam/xlogutils.c | 10 ++++++---- src/include/access/xlogreader.h | 1 + 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 8e15256db8..a495bbac85 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -2218,6 +2218,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible) { char xlogfname[MAXFNAMELEN]; int save_errno; + XLogRecPtr lsn; if (errno == EINTR) continue; @@ -2226,11 +2227,14 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible) XLogFileName(xlogfname, tli, openLogSegNo, wal_segment_size); errno = save_errno; + XLogSegNoOffsetToRecPtr(openLogSegNo, startoffset, + wal_segment_size, lsn); ereport(PANIC, (errcode_for_file_access(), errmsg("could not write to log file %s " - "at offset %u, length %zu: %m", - xlogfname, startoffset, nleft))); + "at offset %u, LSN %X/%X, length %zu: %m", + xlogfname, startoffset, + LSN_FORMAT_ARGS(lsn), nleft))); } nleft -= written; from += written; diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 5a8fe81f82..c3befc44ba 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -1229,9 +1229,10 @@ XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, - "invalid magic number %04X in WAL segment %s, offset %u", + "invalid magic number %04X in WAL segment %s, LSN %X/%X, offset %u", hdr->xlp_magic, fname, + LSN_FORMAT_ARGS(recptr), offset); return false; } @@ -1243,9 +1244,10 @@ XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, - "invalid info bits %04X in WAL segment %s, offset %u", + "invalid info bits %04X in WAL segment %s, LSN %X/%X, offset %u", hdr->xlp_info, fname, + LSN_FORMAT_ARGS(recptr), offset); return false; } @@ -1284,9 +1286,10 @@ XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, /* hmm, first page of file doesn't have a long header? */ report_invalid_record(state, - "invalid info bits %04X in WAL segment %s, offset %u", + "invalid info bits %04X in WAL segment %s, LSN %X/%X, offset %u", hdr->xlp_info, fname, + LSN_FORMAT_ARGS(recptr), offset); return false; } @@ -1303,9 +1306,10 @@ XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, - "unexpected pageaddr %X/%X in WAL segment %s, offset %u", + "unexpected pageaddr %X/%X in WAL segment %s, LSN %X/%X, offset %u", LSN_FORMAT_ARGS(hdr->xlp_pageaddr), fname, + LSN_FORMAT_ARGS(recptr), offset); return false; } @@ -1328,10 +1332,11 @@ XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, - "out-of-sequence timeline ID %u (after %u) in WAL segment %s, offset %u", + "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%X, offset %u", hdr->xlp_tli, state->latestPageTLI, fname, + LSN_FORMAT_ARGS(recptr), offset); return false; } @@ -1556,6 +1561,7 @@ WALRead(XLogReaderState *state, errinfo->wre_req = segbytes; errinfo->wre_read = readbytes; errinfo->wre_off = startoff; + errinfo->wre_lsn = recptr; errinfo->wre_seg = state->seg; return false; } diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index cb07694aea..c6ffb29c05 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -3079,9 +3079,10 @@ ReadRecord(XLogPrefetcher *xlogprefetcher, int emode, XLogFileName(fname, xlogreader->seg.ws_tli, segno, wal_segment_size); ereport(emode_for_corrupt_record(emode, xlogreader->EndRecPtr), - (errmsg("unexpected timeline ID %u in WAL segment %s, offset %u", + (errmsg("unexpected timeline ID %u in WAL segment %s, LSN %X/%X, offset %u", xlogreader->latestPageTLI, fname, + LSN_FORMAT_ARGS(xlogreader->latestPagePtr), offset))); record = NULL; } @@ -3284,14 +3285,16 @@ retry: errno = save_errno; ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen), (errcode_for_file_access(), - errmsg("could not read from WAL segment %s, offset %u: %m", - fname, readOff))); + errmsg("could not read from WAL segment %s, LSN %X/%X, offset %u: %m", + fname, LSN_FORMAT_ARGS(targetPagePtr), + readOff))); } else ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen), (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("could not read from WAL segment %s, offset %u: read %d of %zu", - fname, readOff, r, (Size) XLOG_BLCKSZ))); + errmsg("could not read from WAL segment %s, LSN %X/%X, offset %u: read %d of %zu", + fname, LSN_FORMAT_ARGS(targetPagePtr), + readOff, r, (Size) XLOG_BLCKSZ))); goto next_record_is_invalid; } pgstat_report_wait_end(); diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index 563cba258d..9d171f2ad9 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -1051,15 +1051,17 @@ WALReadRaiseError(WALReadError *errinfo) errno = errinfo->wre_errno; ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read from WAL segment %s, offset %d: %m", - fname, errinfo->wre_off))); + errmsg("could not read from WAL segment %s, LSN %X/%X, offset %d: %m", + fname, LSN_FORMAT_ARGS(errinfo->wre_lsn), + errinfo->wre_off))); } else if (errinfo->wre_read == 0) { ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("could not read from WAL segment %s, offset %d: read %d of %d", - fname, errinfo->wre_off, errinfo->wre_read, + errmsg("could not read from WAL segment %s, LSN %X/%X, offset %d: read %d of %d", + fname, LSN_FORMAT_ARGS(errinfo->wre_lsn), + errinfo->wre_off, errinfo->wre_read, errinfo->wre_req))); } } diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h index e87f91316a..1e47169b5a 100644 --- a/src/include/access/xlogreader.h +++ b/src/include/access/xlogreader.h @@ -386,6 +386,7 @@ typedef struct WALReadError int wre_off; /* Offset we tried to read from. */ int wre_req; /* Bytes requested to be read. */ int wre_read; /* Bytes read by the last read(). */ + XLogRecPtr wre_lsn; /* WAL LSN being read. */ WALOpenSegment wre_seg; /* Segment we tried to read from. */ } WALReadError; -- 2.34.1