From b669f416cee77ef9025b80f9c4201688578447d1 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 11 Feb 2013 22:16:56 +0200 Subject: [PATCH] Fix checkpoint after fast promotion. The intention was to request a regular online checkpoint immediately after end of recovery, when performing "fast promotion". However, because the checkpoint was requested before other backends were allowed to write WAL, the checkpointer process performed a restartpoint rather than a checkpoint. Delay the RequestCheckPoint call until after recovery has truly ended, so that you get a real checkpoint. --- src/backend/access/transam/xlog.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 3155238c58..140f9109a6 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4731,6 +4731,7 @@ StartupXLOG(void) DBState dbstate_at_startup; XLogReaderState *xlogreader; XLogPageReadPrivate private; + bool fast_promoted = false; /* * Read control file and check XLOG status looks valid. @@ -5781,15 +5782,13 @@ StartupXLOG(void) * assigning a new TLI, using a shutdown checkpoint allows us to have * the rule that TLI only changes in shutdown checkpoints, which * allows some extra error checking in xlog_redo. + * + * In fast promotion, only create a lightweight end-of-recovery record + * instead of a full checkpoint. A checkpoint is requested later, after + * we're fully out of recovery mode and already accepting queries. */ if (bgwriterLaunched) { - bool checkpoint_wait = true; - - /* - * If we've been explicitly promoted with fast option, - * end of recovery without a checkpoint if possible. - */ if (fast_promote) { checkPointLoc = ControlFile->prevCheckPoint; @@ -5802,22 +5801,15 @@ StartupXLOG(void) record = ReadCheckpointRecord(xlogreader, checkPointLoc, 1, false); if (record != NULL) { - checkpoint_wait = false; + fast_promoted = true; CreateEndOfRecoveryRecord(); } } - /* - * In most cases we will wait for a full checkpoint to complete. - * - * If not, issue a normal, non-immediate checkpoint but don't wait. - */ - if (checkpoint_wait) + if (!fast_promoted) RequestCheckpoint(CHECKPOINT_END_OF_RECOVERY | CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT); - else - RequestCheckpoint(0); /* No flags */ } else CreateCheckPoint(CHECKPOINT_END_OF_RECOVERY | CHECKPOINT_IMMEDIATE); @@ -5925,6 +5917,15 @@ StartupXLOG(void) * wal sender processes to notice that we've been promoted. */ WalSndWakeup(); + + /* + * If this was a fast promotion, request an (online) checkpoint now. This + * isn't required for consistency, but the last restartpoint might be far + * back, and in case of a crash, recovering from it might take a longer + * than is appropriate now that we're not in standby mode anymore. + */ + if (fast_promoted) + RequestCheckpoint(0); } /*