summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-05-31 19:11:28 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-05-31 19:11:28 +0000
commite4ce3e76ce300e9e732c511c9b3e9bf98d02fd9c (patch)
tree097a69cf2186d1f45401291d8d92bcc7d4fbd87c
parentce93521be046c6438baebdf19d894a4caafc4866 (diff)
downloadpostgresql-e4ce3e76ce300e9e732c511c9b3e9bf98d02fd9c.tar.gz
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.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 26e52899f5..8662a37c21 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.86.2.4 2004/08/11 04:09:12 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.86.2.5 2005/05/31 19:11:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -427,8 +427,8 @@ static uint32 readOff = 0;
static char *readBuf = NULL;
/* 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 StartUpID lastReadSUI;
@@ -1872,6 +1872,37 @@ got_record:;
RecPtr->xlogid, RecPtr->xrecoff);
goto next_record_is_invalid;
}
+ if (!nextmode)
+ {
+ /*
+ * 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))
+ {
+ elog(emode,
+ "ReadRecord: 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))
+ {
+ elog(emode,
+ "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