In the checkpoint written at the end of archive recovery, the WAL page header
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 27 Aug 2009 07:15:41 +0000 (07:15 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 27 Aug 2009 07:15:41 +0000 (07:15 +0000)
was incorrectly initialized with timeline ID 0. That rendered the WAL page
unrecoverable, making a subsequent archive recovery stop at that point.
ThisTimeLineID needs to be initialized before calling AdvanceXLInsertBuffer().

This fixes bug #5011 reported by James Bardin. Backpatch to 8.4, as the bug
was introduced by the changes to use of bgwriter for writing the
end-of-archive-recovery checkpoint. Patch by Tom Lane.

src/backend/access/transam/xlog.c

index 2e4c94e27d02058d749e1870aeaa87f8fec9dc88..ed427785517bfac6da4e9fa777827af237571e8f 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.348 2009/08/12 20:53:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.349 2009/08/27 07:15:41 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -6444,6 +6444,17 @@ CreateCheckPoint(int flags)
        }
    }
 
+   /*
+    * An end-of-recovery checkpoint is created before anyone is allowed to
+    * write WAL. To allow us to write the checkpoint record, temporarily
+    * enable XLogInsertAllowed.  (This also ensures ThisTimeLineID is
+    * initialized, which we need here and in AdvanceXLInsertBuffer.)
+    */
+   if (flags & CHECKPOINT_END_OF_RECOVERY)
+       LocalSetXLogInsertAllowed();
+
+   checkPoint.ThisTimeLineID = ThisTimeLineID;
+
    /*
     * Compute new REDO record ptr = location of next XLOG record.
     *
@@ -6566,20 +6577,6 @@ CreateCheckPoint(int flags)
 
    START_CRIT_SECTION();
 
-   /*
-    * An end-of-recovery checkpoint is created before anyone is allowed to
-    * write WAL. To allow us to write the checkpoint record, temporarily
-    * enable XLogInsertAllowed.
-    */
-   if (flags & CHECKPOINT_END_OF_RECOVERY)
-       LocalSetXLogInsertAllowed();
-
-   /*
-    * This needs to be done after LocalSetXLogInsertAllowed(), else
-    * ThisTimeLineID might still be uninitialized.
-    */
-   checkPoint.ThisTimeLineID = ThisTimeLineID;
-
    /*
     * Now insert the checkpoint record into XLOG.
     */