mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Add test to WAL replay to verify that xl_prev points back to the previous
WAL record; this is necessary to be sure we recognize stale WAL records when a WAL page was only partially written during a system crash.
This commit is contained in:
parent
5b3625f1b7
commit
a91fa39028
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.193 2005/05/20 14:53:25 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.194 2005/05/31 19:10:28 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -417,8 +417,8 @@ static char *readRecordBuf = NULL;
|
|||||||
static uint32 readRecordBufSize = 0;
|
static uint32 readRecordBufSize = 0;
|
||||||
|
|
||||||
/* State information for XLOG reading */
|
/* State information for XLOG reading */
|
||||||
static XLogRecPtr ReadRecPtr;
|
static XLogRecPtr ReadRecPtr; /* start of last record read */
|
||||||
static XLogRecPtr EndRecPtr;
|
static XLogRecPtr EndRecPtr; /* end+1 of last record read */
|
||||||
static XLogRecord *nextRecord = NULL;
|
static XLogRecord *nextRecord = NULL;
|
||||||
static TimeLineID lastPageTLI = 0;
|
static TimeLineID lastPageTLI = 0;
|
||||||
|
|
||||||
@ -2525,6 +2525,37 @@ got_record:;
|
|||||||
record->xl_rmid, RecPtr->xlogid, RecPtr->xrecoff)));
|
record->xl_rmid, RecPtr->xlogid, RecPtr->xrecoff)));
|
||||||
goto next_record_is_invalid;
|
goto next_record_is_invalid;
|
||||||
}
|
}
|
||||||
|
if (randAccess)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We can't exactly verify the prev-link, but surely it should be
|
||||||
|
* less than the record's own address.
|
||||||
|
*/
|
||||||
|
if (!XLByteLT(record->xl_prev, *RecPtr))
|
||||||
|
{
|
||||||
|
ereport(emode,
|
||||||
|
(errmsg("record with incorrect prev-link %X/%X at %X/%X",
|
||||||
|
record->xl_prev.xlogid, record->xl_prev.xrecoff,
|
||||||
|
RecPtr->xlogid, RecPtr->xrecoff)));
|
||||||
|
goto next_record_is_invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Record's prev-link should exactly match our previous location.
|
||||||
|
* This check guards against torn WAL pages where a stale but
|
||||||
|
* valid-looking WAL record starts on a sector boundary.
|
||||||
|
*/
|
||||||
|
if (!XLByteEQ(record->xl_prev, ReadRecPtr))
|
||||||
|
{
|
||||||
|
ereport(emode,
|
||||||
|
(errmsg("record with incorrect prev-link %X/%X at %X/%X",
|
||||||
|
record->xl_prev.xlogid, record->xl_prev.xrecoff,
|
||||||
|
RecPtr->xlogid, RecPtr->xrecoff)));
|
||||||
|
goto next_record_is_invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute total length of record including any appended backup
|
* Compute total length of record including any appended backup
|
||||||
|
Loading…
Reference in New Issue
Block a user