10000 Add test to WAL replay to verify that xl_prev points back to the prev… · fschopp/postgres@e4ce3e7 · GitHub
[go: up one dir, main page]

Skip to content

Commit e4ce3e7

Browse files
committed
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.
1 parent ce93521 commit e4ce3e7

File tree

1 file changed

+34
-3
lines changed
  • src/backend/access/transam

1 file changed

+34
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.86.2.4 2004/08/11 04:09:12 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.86.2.5 2005/05/31 19:11:28 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -427,8 +427,8 @@ static uint32 readOff = 0;
427427
static char *readBuf = NULL;
428428

429429
/* State information for XLOG reading */
430-
static XLogRecPtr ReadRecPtr;
431-
static XLogRecPtr EndRecPtr;
430+
static XLogRecPtr ReadRecPtr; /* start of last record read */
431+
static XLogRecPtr EndRecPtr; /* end+1 of last record read */
432432
static XLogRecord *nextRecord = NULL;
433433
static StartUpID lastReadSUI;
434434

@@ -1872,6 +1872,37 @@ got_record:;
18721872
RecPtr->xlogid, RecPtr->xrecoff);
18731873
goto next_record_is_invalid;
18741874
}
1875+
if (!nextmode)
1876+
{
1877+
/*
1878+
* We can't exactly verify the prev-link, but surely it should be
1879+
* less than the record's own address.
1880+
*/
1881+
if (!XLByteLT(record->xl_prev, *RecPtr))
1882+
{
1883+
elog(emode,
1884+
"ReadRecord: record with incorrect prev-link %X/%X at %X/%X",
1885+
record->xl_prev.xlogid, record->xl_prev.xrecoff,
1886+
RecPtr->xlogid, RecPtr->xrecoff);
1887+
goto next_record_is_invalid;
1888+
}
1889+
}
1890+
else
1891+
{
1892+
/*
1893+
* Record's prev-link should exactly match our previous location.
1894+
* This check guards against torn WAL pages where a stale but
1895+
* valid-looking WAL record starts on a sector boundary.
1896+
*/
1897+
if (!XLByteEQ(record->xl_prev, ReadRecPtr))
1898+
{
1899+
elog(emode,
1900+
"record with incorrect prev-link %X/%X at %X/%X",
1901+
record->xl_prev.xlogid, record->xl_prev.xrecoff,
1902+
RecPtr->xlogid, RecPtr->xrecoff);
1903+
goto next_record_is_invalid;
1904+
}
1905+
}
18751906

18761907
/*
18771908
* Compute total length of record including any appended backup
0