mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
Ensure that we validate the page header of the first page of a WAL file
whenever we start to read within that file. The first page carries extra identification information that really ought to be checked, but as the code stood, this was only checked when we switched sequentially into a new WAL file, or if by chance the starting checkpoint record was within the first page. This patch ensures that we will detect bogus 'long header' information before we start replaying the WAL sequence.
This commit is contained in:
parent
cc7eab38dd
commit
eac825aa68
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.236 2006/04/17 18:55:05 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.237 2006/04/20 04:07:38 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2727,7 +2727,25 @@ ReadRecord(XLogRecPtr *RecPtr, int emode)
|
||||
readFile = XLogFileRead(readId, readSeg, emode);
|
||||
if (readFile < 0)
|
||||
goto next_record_is_invalid;
|
||||
readOff = (uint32) (-1); /* force read to occur below */
|
||||
|
||||
/*
|
||||
* Whenever switching to a new WAL segment, we read the first page of
|
||||
* the file and validate its header, even if that's not where the
|
||||
* target record is. This is so that we can check the additional
|
||||
* identification info that is present in the first page's "long"
|
||||
* header.
|
||||
*/
|
||||
readOff = 0;
|
||||
if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
||||
{
|
||||
ereport(emode,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not read from log file %u, segment %u, offset %u: %m",
|
||||
readId, readSeg, readOff)));
|
||||
goto next_record_is_invalid;
|
||||
}
|
||||
if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode))
|
||||
goto next_record_is_invalid;
|
||||
}
|
||||
|
||||
targetPageOff = ((RecPtr->xrecoff % XLogSegSize) / XLOG_BLCKSZ) * XLOG_BLCKSZ;
|
||||
@ -3036,6 +3054,15 @@ ValidXLOGHeader(XLogPageHeader hdr, int emode)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (readOff == 0)
|
||||
{
|
||||
/* hmm, first page of file doesn't have a long header? */
|
||||
ereport(emode,
|
||||
(errmsg("invalid info bits %04X in log file %u, segment %u, offset %u",
|
||||
hdr->xlp_info, readId, readSeg, readOff)));
|
||||
return false;
|
||||
}
|
||||
|
||||
recaddr.xlogid = readId;
|
||||
recaddr.xrecoff = readSeg * XLogSegSize + readOff;
|
||||
if (!XLByteEQ(hdr->xlp_pageaddr, recaddr))
|
||||
|
Loading…
Reference in New Issue
Block a user