]> granicus.if.org Git - postgresql/commitdiff
Don't delete unarchived WAL files during crash recovery.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 15 Feb 2013 15:25:16 +0000 (17:25 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 15 Feb 2013 15:25:16 +0000 (17:25 +0200)
Bug reported by Jehan-Guillaume (ioguix) de Rorthais. This was introduced
with the change to keep WAL files restored from archive in pg_xlog, in 9.2.

src/backend/access/transam/xlog.c

index 30d877b6fdb9776e3dd8f499ea43ccbe33ed7bab..dabb0945711dcfd2b9699170f5a81da66841d2c5 100644 (file)
@@ -418,6 +418,7 @@ typedef struct XLogCtlData
         * recovery.  Protected by info_lck.
         */
        bool            SharedRecoveryInProgress;
+       bool            SharedInArchiveRecovery;
 
        /*
         * SharedHotStandbyActive indicates if we're still in crash or archive
@@ -622,6 +623,7 @@ static void XLogArchiveCleanup(const char *xlog);
 static void readRecoveryCommandFile(void);
 static void exitArchiveRecovery(TimeLineID endTLI,
                                        uint32 endLogId, uint32 endLogSeg);
+static bool ArchiveRecoveryInProgress(void);
 static bool recoveryStopsHere(XLogRecord *record, bool *includeThis);
 static void recoveryPausesHere(void);
 static void SetLatestXTime(TimestampTz xtime);
@@ -3571,7 +3573,7 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
                        strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
                        strcmp(xlde->d_name + 8, lastoff + 8) <= 0)
                {
-                       if (RecoveryInProgress() || XLogArchiveCheckDone(xlde->d_name))
+                       if (ArchiveRecoveryInProgress() || XLogArchiveCheckDone(xlde->d_name))
                        {
                                snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
 
@@ -5289,6 +5291,7 @@ XLOGShmemInit(void)
         */
        XLogCtl->XLogCacheBlck = XLOGbuffers - 1;
        XLogCtl->SharedRecoveryInProgress = true;
+       XLogCtl->SharedInArchiveRecovery = false;
        XLogCtl->SharedHotStandbyActive = false;
        XLogCtl->WalWriterSleeping = false;
        XLogCtl->Insert.currpage = (XLogPageHeader) (XLogCtl->pages);
@@ -5680,6 +5683,7 @@ readRecoveryCommandFile(void)
 
        /* Enable fetching from archive recovery area */
        InArchiveRecovery = true;
+       XLogCtl->SharedInArchiveRecovery = true;
 
        /*
         * If user specified recovery_target_timeline, validate it or compute the
@@ -5718,11 +5722,16 @@ exitArchiveRecovery(TimeLineID endTLI, uint32 endLogId, uint32 endLogSeg)
 {
        char            recoveryPath[MAXPGPATH];
        char            xlogpath[MAXPGPATH];
+       /* use volatile pointer to prevent code rearrangement */
+       volatile XLogCtlData *xlogctl = XLogCtl;
 
        /*
         * We are no longer in archive recovery state.
         */
        InArchiveRecovery = false;
+       SpinLockAcquire(&xlogctl->info_lck);
+       xlogctl->SharedInArchiveRecovery = false;
+       SpinLockRelease(&xlogctl->info_lck);
 
        /*
         * Update min recovery point one last time.
@@ -7314,6 +7323,25 @@ RecoveryInProgress(void)
        }
 }
 
+/*
+ * Are we currently in archive recovery? In the startup process, you can just
+ * check InArchiveRecovery variable instead.
+ */
+static bool
+ArchiveRecoveryInProgress()
+{
+       bool            result;
+       /* use volatile pointer to prevent code rearrangement */
+       volatile XLogCtlData *xlogctl = XLogCtl;
+
+       /* spinlock is essential on machines with weak memory ordering! */
+       SpinLockAcquire(&xlogctl->info_lck);
+       result = xlogctl->SharedInArchiveRecovery;
+       SpinLockRelease(&xlogctl->info_lck);
+
+       return result;
+}
+
 /*
  * Is HotStandby active yet? This is only important in special backends
  * since normal backends won't ever be able to connect until this returns