]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Add test to WAL replay to verify that xl_prev points back to the previous
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 May 2005 19:10:39 +0000 (19:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 May 2005 19:10:39 +0000 (19:10 +0000)
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.

src/backend/access/transam/xlog.c

index 682a6323e0e6eb6f5cecd3086482552920b86a61..8b086b78f3cafe0e846726f484e46a971dbc1ae9 100644 (file)
@@ -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.180.4.2 2005/04/15 22:49:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.180.4.3 2005/05/31 19:10:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -423,8 +423,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;
 
@@ -2503,6 +2503,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