diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-05-31 19:10:28 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-05-31 19:10:28 +0000 |
commit | a91fa3902863489bf8f73881543baa0eb59f2683 (patch) | |
tree | 0642fe014f1d2fcb080b8e516f1542daf203623c | |
parent | 5b3625f1b778246a1f783e405c57e8baca2e502b (diff) | |
download | postgresql-a91fa3902863489bf8f73881543baa0eb59f2683.tar.gz postgresql-a91fa3902863489bf8f73881543baa0eb59f2683.zip |
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.
-rw-r--r-- | src/backend/access/transam/xlog.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 35d914d8dde..2352313b051 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * 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; /* State information for XLOG reading */ -static XLogRecPtr ReadRecPtr; -static XLogRecPtr EndRecPtr; +static XLogRecPtr ReadRecPtr; /* start of last record read */ +static XLogRecPtr EndRecPtr; /* end+1 of last record read */ static XLogRecord *nextRecord = NULL; static TimeLineID lastPageTLI = 0; @@ -2525,6 +2525,37 @@ got_record:; record->xl_rmid, RecPtr->xlogid, RecPtr->xrecoff))); 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 |