Skip to content

Commit 78974cf

Browse files
committed
In standby mode, suppress repeated LOG messages about a corrupt record,
which just indicates that we've reached the end of valid WAL found in the standby.
1 parent b4fd1e2 commit 78974cf

File tree

1 file changed

+54
-36
lines changed
  • src/backend/access/transam

1 file changed

+54
-36
lines changed

src/backend/access/transam/xlog.c

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.396 2010/04/15 03:05:59 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.397 2010/04/16 08:58:16 heikki Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -539,7 +539,7 @@ static int XLogFileReadAnyTLI(uint32 log, uint32 seg, int emode,
539539
int sources);
540540
static bool XLogPageRead(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt,
541541
bool randAccess);
542-
static int emode_for_corrupt_record(int emode);
542+
static int emode_for_corrupt_record(int emode, XLogRecPtr RecPtr);
543543
static void XLogFileClose(void);
544544
static bool RestoreArchivedFile(char *path, const char *xlogfname,
545545
const char *recovername, off_t expectedSize);
@@ -3543,7 +3543,7 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode)
35433543
memcpy(&bkpb, blk, sizeof(BkpBlock));
35443544
if (bkpb.hole_offset + bkpb.hole_length > BLCKSZ)
35453545
{
3546-
ereport(emode,
3546+
ereport(emode_for_corrupt_record(emode, recptr),
35473547
(errmsg("incorrect hole size in record at %X/%X",
35483548
recptr.xlogid, recptr.xrecoff)));
35493549
return false;
@@ -3556,7 +3556,7 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode)
35563556
/* Check that xl_tot_len agrees with our calculation */
35573557
if (blk != (char *) record + record->xl_tot_len)
35583558
{
3559-
ereport(emode,
3559+
ereport(emode_for_corrupt_record(emode, recptr),
35603560
(errmsg("incorrect total length in record at %X/%X",
35613561
recptr.xlogid, recptr.xrecoff)));
35623562
return false;
@@ -3569,7 +3569,7 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode)
35693569

35703570
if (!EQ_CRC32(record->xl_crc, crc))
35713571
{
3572-
ereport(emode,
3572+
ereport(emode_for_corrupt_record(emode, recptr),
35733573
(errmsg("incorrect resource manager data checksum in record at %X/%X",
35743574
recptr.xlogid, recptr.xrecoff)));
35753575
return false;
@@ -3674,15 +3674,15 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
36743674
}
36753675
else if (targetRecOff < pageHeaderSize)
36763676
{
3677-
ereport(emode_for_corrupt_record(emode),
3677+
ereport(emode_for_corrupt_record(emode, *RecPtr),
36783678
(errmsg("invalid record offset at %X/%X",
36793679
RecPtr->xlogid, RecPtr->xrecoff)));
36803680
goto next_record_is_invalid;
36813681
}
36823682
if ((((XLogPageHeader) readBuf)->xlp_info & XLP_FIRST_IS_CONTRECORD) &&
36833683
targetRecOff == pageHeaderSize)
36843684
{
3685-
ereport(emode_for_corrupt_record(emode),
3685+
ereport(emode_for_corrupt_record(emode, *RecPtr),
36863686
(errmsg("contrecord is requested by %X/%X",
36873687
RecPtr->xlogid, RecPtr->xrecoff)));
36883688
goto next_record_is_invalid;
@@ -3697,15 +3697,15 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
36973697
{
36983698
if (record->xl_len != 0)
36993699
{
3700-
ereport(emode_for_corrupt_record(emode),
3700+
ereport(emode_for_corrupt_record(emode, *RecPtr),
37013701
(errmsg("invalid xlog switch record at %X/%X",
37023702
RecPtr->xlogid, RecPtr->xrecoff)));
37033703
goto next_record_is_invalid;
37043704
}
37053705
}
37063706
else if (record->xl_len == 0)
37073707
{
3708-
ereport(emode_for_corrupt_record(emode),
3708+
ereport(emode_for_corrupt_record(emode, *RecPtr),
37093709
(errmsg("record with zero length at %X/%X",
37103710
RecPtr->xlogid, RecPtr->xrecoff)));
37113711
goto next_record_is_invalid;
@@ -3714,14 +3714,14 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
37143714
record->xl_tot_len > SizeOfXLogRecord + record->xl_len +
37153715
XLR_MAX_BKP_BLOCKS * (sizeof(BkpBlock) + BLCKSZ))
37163716
{
3717-
ereport(emode_for_corrupt_record(emode),
3717+
ereport(emode_for_corrupt_record(emode, *RecPtr),
37183718
(errmsg("invalid record length at %X/%X",
37193719
RecPtr->xlogid, RecPtr->xrecoff)));
37203720
goto next_record_is_invalid;
37213721
}
37223722
if (record->xl_rmid > RM_MAX_ID)
37233723
{
3724-
ereport(emode_for_corrupt_record(emode),
3724+
ereport(emode_for_corrupt_record(emode, *RecPtr),
37253725
(errmsg("invalid resource manager ID %u at %X/%X",
37263726
record->xl_rmid, RecPtr->xlogid, RecPtr->xrecoff)));
37273727
goto next_record_is_invalid;
@@ -3734,7 +3734,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
37343734
*/
37353735
if (!XLByteLT(record->xl_prev, *RecPtr))
37363736
{
3737-
ereport(emode_for_corrupt_record(emode),
3737+
ereport(emode_for_corrupt_record(emode, *RecPtr),
37383738
(errmsg("record with incorrect prev-link %X/%X at %X/%X",
37393739
record->xl_prev.xlogid, record->xl_prev.xrecoff,
37403740
RecPtr->xlogid, RecPtr->xrecoff)));
@@ -3750,7 +3750,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
37503750
*/
37513751
if (!XLByteEQ(record->xl_prev, ReadRecPtr))
37523752
{
3753-
ereport(emode_for_corrupt_record(emode),
3753+
ereport(emode_for_corrupt_record(emode, *RecPtr),
37543754
(errmsg("record with incorrect prev-link %X/%X at %X/%X",
37553755
record->xl_prev.xlogid, record->xl_prev.xrecoff,
37563756
RecPtr->xlogid, RecPtr->xrecoff)));
@@ -3779,7 +3779,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
37793779
{
37803780
readRecordBufSize = 0;
37813781
/* We treat this as a "bogus data" condition */
3782-
ereport(emode_for_corrupt_record(emode),
3782+
ereport(emode_for_corrupt_record(emode, *RecPtr),
37833783
(errmsg("record length %u at %X/%X too long",
37843784
total_len, RecPtr->xlogid, RecPtr->xrecoff)));
37853785
goto next_record_is_invalid;
@@ -3819,7 +3819,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38193819
/* Check that the continuation record looks valid */
38203820
if (!(((XLogPageHeader) readBuf)->xlp_info & XLP_FIRST_IS_CONTRECORD))
38213821
{
3822-
ereport(emode_for_corrupt_record(emode),
3822+
ereport(emode_for_corrupt_record(emode, *RecPtr),
38233823
(errmsg("there is no contrecord flag in log file %u, segment %u, offset %u",
38243824
readId, readSeg, readOff)));
38253825
goto next_record_is_invalid;
@@ -3829,7 +3829,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38293829
if (contrecord->xl_rem_len == 0 ||
38303830
total_len != (contrecord->xl_rem_len + gotlen))
38313831
{
3832-
ereport(emode_for_corrupt_record(emode),
3832+
ereport(emode_for_corrupt_record(emode, *RecPtr),
38333833
(errmsg("invalid contrecord length %u in log file %u, segment %u, offset %u",
38343834
contrecord->xl_rem_len,
38353835
readId, readSeg, readOff)));
@@ -3847,7 +3847,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38473847
contrecord->xl_rem_len);
38483848
break;
38493849
}
3850-
if (!RecordIsValid(record, *RecPtr, emode_for_corrupt_record(emode)))
3850+
if (!RecordIsValid(record, *RecPtr, emode))
38513851
goto next_record_is_invalid;
38523852
pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf);
38533853
EndRecPtr.xlogid = readId;
@@ -3861,7 +3861,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38613861
}
38623862

38633863
/* Record does not cross a page boundary */
3864-
if (!RecordIsValid(record, *RecPtr, emode_for_corrupt_record(emode)))
3864+
if (!RecordIsValid(record, *RecPtr, emode))
38653865
goto next_record_is_invalid;
38663866
EndRecPtr.xlogid = RecPtr->xlogid;
38673867
EndRecPtr.xrecoff = RecPtr->xrecoff + MAXALIGN(total_len);
@@ -3914,16 +3914,19 @@ ValidXLOGHeader(XLogPageHeader hdr, int emode)
39143914
{
39153915
XLogRecPtr recaddr;
39163916

3917+
recaddr.xlogid = readId;
3918+
recaddr.xrecoff = readSeg * XLogSegSize + readOff;
3919+
39173920
if (hdr->xlp_magic != XLOG_PAGE_MAGIC)
39183921
{
3919-
ereport(emode,
3922+
ereport(emode_for_corrupt_record(emode, recaddr),
39203923
(errmsg("invalid magic number %04X in log file %u, segment %u, offset %u",
39213924
hdr->xlp_magic, readId, readSeg, readOff)));
39223925
return false;
39233926
}
39243927
if ((hdr->xlp_info & ~XLP_ALL_FLAGS) != 0)
39253928
{
3926-
ereport(emode,
3929+
ereport(emode_for_corrupt_record(emode, recaddr),
39273930
(errmsg("invalid info bits %04X in log file %u, segment %u, offset %u",
39283931
hdr->xlp_info, readId, readSeg, readOff)));
39293932
return false;
@@ -3945,22 +3948,22 @@ ValidXLOGHeader(XLogPageHeader hdr, int emode)
39453948
longhdr->xlp_sysid);
39463949
snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
39473950
ControlFile->system_identifier);
3948-
ereport(emode,
3951+
ereport(emode_for_corrupt_record(emode, recaddr),
39493952
(errmsg("WAL file is from different database system"),
39503953
errdetail("WAL file database system identifier is %s, pg_control database system identifier is %s.",
39513954
fhdrident_str, sysident_str)));
39523955
return false;
39533956
}
39543957
if (longhdr->xlp_seg_size != XLogSegSize)
39553958
{
3956-
ereport(emode,
3959+
ereport(emode_for_corrupt_record(emode, recaddr),
39573960
(errmsg("WAL file is from different database system"),
39583961
errdetail("Incorrect XLOG_SEG_SIZE in page header.")));
39593962
return false;
39603963
}
39613964
if (longhdr->xlp_xlog_blcksz != XLOG_BLCKSZ)
39623965
{
3963-
ereport(emode,
3966+
ereport(emode_for_corrupt_record(emode, recaddr),
39643967
(errmsg("WAL file is from different database system"),
39653968
errdetail("Incorrect XLOG_BLCKSZ in page header.")));
39663969
return false;
@@ -3969,17 +3972,15 @@ ValidXLOGHeader(XLogPageHeader hdr, int emode)
39693972
else if (readOff == 0)
39703973
{
39713974
/* hmm, first page of file doesn't have a long header? */
3972-
ereport(emode,
3975+
ereport(emode_for_corrupt_record(emode, recaddr),
39733976
(errmsg("invalid info bits %04X in log file %u, segment %u, offset %u",
39743977
hdr->xlp_info, readId, readSeg, readOff)));
39753978
return false;
39763979
}
39773980

3978-
recaddr.xlogid = readId;
3979-
recaddr.xrecoff = readSeg * XLogSegSize + readOff;
39803981
if (!XLByteEQ(hdr->xlp_pageaddr, recaddr))
39813982
{
3982-
ereport(emode,
3983+
ereport(emode_for_corrupt_record(emode, recaddr),
39833984
(errmsg("unexpected pageaddr %X/%X in log file %u, segment %u, offset %u",
39843985
hdr->xlp_pageaddr.xlogid, hdr->xlp_pageaddr.xrecoff,
39853986
readId, readSeg, readOff)));
@@ -3991,7 +3992,7 @@ ValidXLOGHeader(XLogPageHeader hdr, int emode)
39913992
*/
39923993
if (!list_member_int(expectedTLIs, (int) hdr->xlp_tli))
39933994
{
3994-
ereport(emode,
3995+
ereport(emode_for_corrupt_record(emode, recaddr),
39953996
(errmsg("unexpected timeline ID %u in log file %u, segment %u, offset %u",
39963997
hdr->xlp_tli,
39973998
readId, readSeg, readOff)));
@@ -4009,7 +4010,7 @@ ValidXLOGHeader(XLogPageHeader hdr, int emode)
40094010
*/
40104011
if (hdr->xlp_tli < lastPageTLI)
40114012
{
4012-
ereport(emode,
4013+
ereport(emode_for_corrupt_record(emode, recaddr),
40134014
(errmsg("out-of-sequence timeline ID %u (after %u) in log file %u, segment %u, offset %u",
40144015
hdr->xlp_tli, lastPageTLI,
40154016
readId, readSeg, readOff)));
@@ -9245,36 +9246,35 @@ XLogPageRead(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt,
92459246
readOff = 0;
92469247
if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
92479248
{
9248-
ereport(emode_for_corrupt_record(emode),
9249+
ereport(emode_for_corrupt_record(emode, *RecPtr),
92499250
(errcode_for_file_access(),
92509251
errmsg("could not read from log file %u, segment %u, offset %u: %m",
92519252
readId, readSeg, readOff)));
92529253
goto next_record_is_invalid;
92539254
}
9254-
if (!ValidXLOGHeader((XLogPageHeader) readBuf,
9255-
emode_for_corrupt_record(emode)))
9255+
if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode))
92569256
goto next_record_is_invalid;
92579257
}
92589258

92599259
/* Read the requested page */
92609260
readOff = targetPageOff;
92619261
if (lseek(readFile, (off_t) readOff, SEEK_SET) < 0)
92629262
{
9263-
ereport(emode_for_corrupt_record(emode),
9263+
ereport(emode_for_corrupt_record(emode, *RecPtr),
92649264
(errcode_for_file_access(),
92659265
errmsg("could not seek in log file %u, segment %u to offset %u: %m",
92669266
readId, readSeg, readOff)));
92679267
goto next_record_is_invalid;
92689268
}
92699269
if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
92709270
{
9271-
ereport(emode_for_corrupt_record(emode),
9271+
ereport(emode_for_corrupt_record(emode, *RecPtr),
92729272
(errcode_for_file_access(),
92739273
errmsg("could not read from log file %u, segment %u, offset %u: %m",
92749274
readId, readSeg, readOff)));
92759275
goto next_record_is_invalid;
92769276
}
9277-
if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode_for_corrupt_record(emode)))
9277+
if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode))
92789278
goto next_record_is_invalid;
92799279

92809280
Assert(targetId == readId);
@@ -9316,10 +9316,17 @@ XLogPageRead(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt,
93169316
* 'emode' is the error mode that would be used to report a file-not-found
93179317
* or legitimate end-of-WAL situation. It is upgraded to WARNING or PANIC
93189318
* if a corrupt record is not expected at this point.
9319+
*
9320+
* NOTE: This function remembers the RecPtr value it was last called with,
9321+
* to suppress repeated messages about the same record. Only call this when
9322+
* you are about to ereport(), or you might cause a later message to be
9323+
* erroneously suppressed.
93199324
*/
93209325
static int
9321-
emode_for_corrupt_record(int emode)
9326+
emode_for_corrupt_record(int emode, XLogRecPtr RecPtr)
93229327
{
9328+
static XLogRecPtr lastComplaint = {0, 0};
9329+
93239330
/*
93249331
* We don't expect any invalid records in archive or in records streamed
93259332
* from master. Files in the archive should be complete, and we should
@@ -9340,6 +9347,17 @@ emode_for_corrupt_record(int emode)
93409347
if (emode < WARNING)
93419348
emode = WARNING;
93429349
}
9350+
/*
9351+
* If we retry reading a record in pg_xlog, only complain on the first
9352+
* time to keep the noise down.
9353+
*/
9354+
else if (emode == LOG)
9355+
{
9356+
if (XLByteEQ(RecPtr, lastComplaint))
9357+
emode = DEBUG1;
9358+
else
9359+
lastComplaint = RecPtr;
9360+
}
93439361
return emode;
93449362
}
93459363

0 commit comments

Comments
 (0)