]> granicus.if.org Git - postgresql/commitdiff
Check if we've reached end-of-backup point also if no redo is required.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 19 Dec 2012 12:13:23 +0000 (14:13 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 19 Dec 2012 12:22:00 +0000 (14:22 +0200)
If you restored from a backup taken from a standby, and the last record in
the backup is the checkpoint record, ie. there is no redo required except
for the checkpoint record, we would fail to notice that we've reached the
end-of-backup point, and the database is consistent. The result was an
error "WAL ends before end of online backup". To fix, move the
have-we-reached-end-of-backup check into CheckRecoveryConsistency(), which
is already responsible for similar checks with minRecoveryPoint, and is
called in the right places.

Backpatch to 9.2, this check and bug did not exist before that.

src/backend/access/transam/xlog.c

index 2deb7e5d89bf1177b2d32c16ff6550aae6928778..5b156f9c70e009b28cf8f1dc7d6fdc5b3997e8e2 100644 (file)
@@ -5963,27 +5963,6 @@ StartupXLOG(void)
                                /* Pop the error context stack */
                                error_context_stack = errcallback.previous;
 
-                               if (!XLogRecPtrIsInvalid(ControlFile->backupEndPoint) &&
-                                       XLByteLE(ControlFile->backupEndPoint, EndRecPtr))
-                               {
-                                       /*
-                                        * We have reached the end of base backup, the point where
-                                        * the minimum recovery point in pg_control indicates. The
-                                        * data on disk is now consistent. Reset backupStartPoint
-                                        * and backupEndPoint.
-                                        */
-                                       elog(DEBUG1, "end of backup reached");
-
-                                       LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
-
-                                       MemSet(&ControlFile->backupStartPoint, 0, sizeof(XLogRecPtr));
-                                       MemSet(&ControlFile->backupEndPoint, 0, sizeof(XLogRecPtr));
-                                       ControlFile->backupEndRequired = false;
-                                       UpdateControlFile();
-
-                                       LWLockRelease(ControlFileLock);
-                               }
-
                                /*
                                 * Update lastReplayedEndRecPtr after this record has been
                                 * successfully replayed.
@@ -6390,6 +6369,34 @@ CheckRecoveryConsistency(void)
        if (XLogRecPtrIsInvalid(minRecoveryPoint))
                return;
 
+       /*
+        * Have we reached the point where our base backup was completed?
+        */
+       if (!XLogRecPtrIsInvalid(ControlFile->backupEndPoint) &&
+               XLByteLE(ControlFile->backupEndPoint, EndRecPtr))
+       {
+               /*
+                * We have reached the end of base backup, as indicated by pg_control.
+                * The data on disk is now consistent. Reset backupStartPoint and
+                * backupEndPoint, and update minRecoveryPoint to make sure we don't
+                * allow starting up at an earlier point even if recovery is stopped
+                * and restarted soon after this.
+                */
+               elog(DEBUG1, "end of backup reached");
+
+               LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+
+               if (XLByteLT(ControlFile->minRecoveryPoint, EndRecPtr))
+                       ControlFile->minRecoveryPoint = EndRecPtr;
+
+               MemSet(&ControlFile->backupStartPoint, 0, sizeof(XLogRecPtr));
+               MemSet(&ControlFile->backupEndPoint, 0, sizeof(XLogRecPtr));
+               ControlFile->backupEndRequired = false;
+               UpdateControlFile();
+
+               LWLockRelease(ControlFileLock);
+       }
+
        /*
         * Have we passed our safe starting point? Note that minRecoveryPoint
         * is known to be incorrectly set if ControlFile->backupEndRequired,