In the checkpoint written at the end of archive recovery, the WAL page header

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.
This commit is contained in:
Heikki Linnakangas 2009-08-27 07:15:41 +00:00
parent a814170d89
commit 9cd6685f91
1 changed files with 12 additions and 15 deletions

View 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.
*/