In the checkpoint written at the end of archive recovery, the WAL page header
authorHeikki Linnakangas <heikki@enterprisedb.com>
Thu, 27 Aug 2009 07:15:41 +0000 (07:15 +0000)
committerHeikki Linnakangas <heikki@enterprisedb.com>
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 cc6be167ef6ecb52e193890603f8ad5419f996ec..8f9a0ae639febd5aa3a6925b4b8301a89772294c 100644 (file)
@@ -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.
         */