Disable xlog-triggered checkpoints and progress-tracking during recovery
authorHeikki Linnakangas <heikki@enterprisedb.com>
Tue, 27 Jan 2009 19:27:27 +0000 (21:27 +0200)
committerHeikki Linnakangas <heikki@enterprisedb.com>
Tue, 27 Jan 2009 19:27:27 +0000 (21:27 +0200)
again. Plus a bunch of other small stuff.

src/backend/access/transam/xlog.c
src/backend/postmaster/bgwriter.c

index 06ff2a5147045fa83f58ba9511324a405b75e80f..ac87519aeccbe0ccaf6c29ce35feeb7cafeda2f6 100644 (file)
@@ -358,14 +358,14 @@ typedef struct XLogCtlData
        bool            SharedRecoveryProcessingMode;
 
        /*
-        * This is somewhat similar to RedoRecPtr. It's the location of the
-        * most recent checkpoint record we've seen in the WAL replay.
-        * (ignoring records that are not safe to use as restartpoints because
-        * a resource manager returned false in rm_safe_restartpoint())
+        * During recovery, we keep a copy of the latest checkpoint record
+        * here. It's used by the background writer when it wants to create
+        * a restartpoint.
+        *
+        * is info_lck spinlock a bit too light-weight to protect this?
         */
-       XLogRecPtr      RestartRedoPtr;
-       CheckPoint      restartPoint; /* XXX is info_lck spinlock a bit too light-weight to protect this? */
-       XLogRecPtr      ReadRecPtr; /* last read pointer during recovery */
+       XLogRecPtr      lastCheckPointPtr;
+       CheckPoint      lastCheckPoint;
 
        slock_t         info_lck;               /* locks shared variables shown above */
 } XLogCtlData;
@@ -5280,18 +5280,6 @@ StartupXLOG(void)
                                }
 #endif
 
-                               /*
-                                * Advertise new read pointer. 
-                                */
-                               {
-                                       /* use volatile pointer to prevent code rearrangement */
-                                       volatile XLogCtlData *xlogctl = XLogCtl;
-
-                                       SpinLockAcquire(&xlogctl->info_lck);
-                                       xlogctl->ReadRecPtr = record->xl_prev;
-                                       SpinLockRelease(&xlogctl->info_lck);
-                               }
-
                                /*
                                 * Have we reached our recovery target?
                                 */
@@ -5326,13 +5314,13 @@ StartupXLOG(void)
 
                                /*
                                 * Have we reached our safe starting point? If so, we can
-                                * signal Postmaster to enter consistent recovery mode.
+                                * signal postmaster to enter consistent recovery mode.
                                 *
                                 * There are two points in the log we must pass. The first is
                                 * the minRecoveryPoint, which is the LSN at the time the
                                 * base backup was taken that we are about to rollfoward from.
                                 * If recovery has ever crashed or was stopped there is 
-                                * another point also: minSafeStartPoint, which we know the
+                                * another point also: minSafeStartPoint, which is the
                                 * latest LSN that recovery could have reached prior to crash.
                                 */
                                if (!reachedSafeStartPoint && 
@@ -5781,18 +5769,9 @@ GetInsertRecPtr(void)
        volatile XLogCtlData *xlogctl = XLogCtl;
        XLogRecPtr      recptr;
 
-       if (IsRecoveryProcessingMode())
-       {
-               SpinLockAcquire(&xlogctl->info_lck);
-               recptr = xlogctl->LogwrtRqst.Write;
-               SpinLockRelease(&xlogctl->info_lck);
-       }
-       else
-       {
-               SpinLockAcquire(&xlogctl->info_lck);
-               recptr = xlogctl->ReadRecPtr;
-               SpinLockRelease(&xlogctl->info_lck);
-       }
+       SpinLockAcquire(&xlogctl->info_lck);
+       recptr = xlogctl->LogwrtRqst.Write;
+       SpinLockRelease(&xlogctl->info_lck);
 
        return recptr;
 }
@@ -6320,13 +6299,8 @@ CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
 }
 
 /*
- * Set a recovery restart point if appropriate
- *
- * This is similar to CreateCheckPoint, but is used during WAL recovery
- * to establish a point from which recovery can roll forward without
- * replaying the entire recovery log.  This function is called each time
- * a checkpoint record is read from XLOG; it must determine whether a
- * restartpoint is needed or not.
+ * Set a recovery restart point if appropriate.
+ * This function is called each time a checkpoint record is read from XLOG.
  */
 static void
 RecoveryRestartPoint(const CheckPoint *checkPoint)
@@ -6355,20 +6329,23 @@ RecoveryRestartPoint(const CheckPoint *checkPoint)
        }
 
        SpinLockAcquire(&xlogctl->info_lck);
-       XLogCtl->RestartRedoPtr = ReadRecPtr;
-       memcpy(&XLogCtl->restartPoint, checkPoint, sizeof(CheckPoint));
+       XLogCtl->lastCheckPointPtr = ReadRecPtr;
+       memcpy(&XLogCtl->lastCheckPoint, checkPoint, sizeof(CheckPoint));
        SpinLockRelease(&xlogctl->info_lck);
 
        /*
         * XXX: Should we try to perform restartpoints if we're not in consistent
-        * recovery?
+        * recovery? The bgwriter isn't doing it for us in that case.
         */
 }
 
 /*
+ * This is similar to CreateCheckPoint, but is used during WAL recovery
+ * to establish a point from which recovery can roll forward without
+ * replaying the entire recovery log.
+ *
  * As of 8.4, RestartPoints are always created by the bgwriter
- * once we have reachedSafeStartPoint. We use bgwriter's shared memory
- * area wherever we call it from, to keep better code structure.
+ * once we have reachedSafeStartPoint.
  */
 void
 CreateRestartPoint(int flags)
@@ -6378,11 +6355,6 @@ CreateRestartPoint(int flags)
        /* use volatile pointer to prevent code rearrangement */
        volatile XLogCtlData *xlogctl = XLogCtl;
 
-       SpinLockAcquire(&xlogctl->info_lck);
-       redoRecPtr = xlogctl->RestartRedoPtr;
-       memcpy(&restartPoint, &XLogCtl->restartPoint, sizeof(CheckPoint));
-       SpinLockRelease(&xlogctl->info_lck);
-
        /*
         * If the last checkpoint record we've replayed is already our last
         * restartpoint, we're done.
@@ -6390,7 +6362,7 @@ CreateRestartPoint(int flags)
        if (XLByteLE(redoRecPtr, ControlFile->checkPointCopy.redo))
        {
                ereport(DEBUG2,
-                               (errmsg("restartpoint already performed at %X/%X",
+                               (errmsg("skipping restartpoint, already performed at %X/%X",
                                                restartPoint.redo.xlogid, restartPoint.redo.xrecoff)));
                return;
        }
@@ -6410,10 +6382,24 @@ CreateRestartPoint(int flags)
        /*
         * Acquire CheckpointLock to ensure only one restartpoint happens at a time.
         * We rely on this lock to ensure that the startup process doesn't exit
-        * Recovery while we are half way through a restartpoint.
+        * Recovery while we are half way through a restartpoint. XXX ?
         */
        LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
 
+       /* Check that we're still in recovery mode. */
+       if (!IsRecoveryProcessingMode())
+       {
+               ereport(DEBUG2,
+                               (errmsg("skipping restartpoint, recovery has already ended")));
+               LWLockRelease(CheckpointLock);
+               return;
+       }
+
+       SpinLockAcquire(&xlogctl->info_lck);
+       redoRecPtr = xlogctl->lastCheckPointPtr;
+       memcpy(&restartPoint, &XLogCtl->lastCheckPoint, sizeof(CheckPoint));
+       SpinLockRelease(&xlogctl->info_lck);
+
        CheckPointGuts(restartPoint.redo, flags);
 
        /*
index a4c12de2b02cd3550644174d74d3877e01ff8c40..8cbb7a37449ff3de3d7595f0a9579d1614533909 100644 (file)
@@ -478,7 +478,8 @@ BackgroundWriterMain(void)
                         * Initialize bgwriter-private variables used during checkpoint.
                         */
                        ckpt_active = true;
-                       ckpt_start_recptr = GetInsertRecPtr();
+                       if (!BgWriterRecoveryMode)
+                               ckpt_start_recptr = GetInsertRecPtr();
                        ckpt_start_time = now;
                        ckpt_cached_elapsed = 0;