Update the location of last removed WAL segment in shared memory only
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 12 Apr 2010 10:40:43 +0000 (10:40 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 12 Apr 2010 10:40:43 +0000 (10:40 +0000)
after actually removing one, so that if we can't remove segments because
WAL archiving is lagging behind, we don't unnecessarily forbid streaming
the old not-yet-archived segments that are still perfectly valid. Per
suggestion from Fujii Masao.

src/backend/access/transam/xlog.c
src/include/access/xlog_internal.h

index c5b7f7a98ceaf4c0411ce0dcd00b30159eb15e5b..379c6f11750b26ea4feff7f777d333668b302ca9 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.392 2010/04/12 09:52:29 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.393 2010/04/12 10:40:42 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -546,6 +546,7 @@ static void ExecuteRecoveryCommand(char *command, char *commandName,
                       bool failOnerror);
 static void PreallocXlogFiles(XLogRecPtr endptr);
 static void RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr);
+static void UpdateLastRemovedPtr(char *filename);
 static void ValidateXLOGDirectoryStructure(void);
 static void CleanupBackupHistory(void);
 static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force);
@@ -3168,6 +3169,31 @@ XLogGetLastRemoved(uint32 *log, uint32 *seg)
    SpinLockRelease(&xlogctl->info_lck);
 }
 
+/*
+ * Update the last removed log/seg pointer in shared memory, to reflect
+ * that the given XLOG file has been removed.
+ */
+static void
+UpdateLastRemovedPtr(char *filename)
+{
+   /* use volatile pointer to prevent code rearrangement */
+   volatile XLogCtlData *xlogctl = XLogCtl;
+   uint32      tli,
+               log,
+               seg;
+
+   XLogFromFileName(filename, &tli, &log, &seg);
+
+   SpinLockAcquire(&xlogctl->info_lck);
+   if (log > xlogctl->lastRemovedLog ||
+       (log == xlogctl->lastRemovedLog && seg > xlogctl->lastRemovedSeg))
+   {
+       xlogctl->lastRemovedLog = log;
+       xlogctl->lastRemovedSeg = seg;
+   }
+   SpinLockRelease(&xlogctl->info_lck);
+}
+
 /*
  * Recycle or remove all log files older or equal to passed log/seg#
  *
@@ -3189,20 +3215,8 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
    char        newpath[MAXPGPATH];
 #endif
    struct stat statbuf;
-   /* use volatile pointer to prevent code rearrangement */
-   volatile XLogCtlData *xlogctl = XLogCtl;
 
-   /* Update the last removed location in shared memory first */
-   SpinLockAcquire(&xlogctl->info_lck);
-   if (log > xlogctl->lastRemovedLog ||
-       (log == xlogctl->lastRemovedLog && seg > xlogctl->lastRemovedSeg))
-   {
-       xlogctl->lastRemovedLog = log;
-       xlogctl->lastRemovedSeg = seg;
-   }
-   SpinLockRelease(&xlogctl->info_lck);
-
-   elog(DEBUG1, "removing WAL segments older than %X/%X", log, seg);
+   elog(DEBUG2, "removing WAL segments older than %X/%X", log, seg);
 
    /*
     * Initialize info about where to try to recycle to.  We allow recycling
@@ -3252,6 +3266,9 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
            {
                snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
 
+               /* Update the last removed location in shared memory first */
+               UpdateLastRemovedPtr(xlde->d_name);
+
                /*
                 * Before deleting the file, see if it can be recycled as a
                 * future log segment. Only recycle normal files, pg_standby
index c93e3848e87368429e5dbb24f9aaea18168f2a5f..fa21f0a916a3348bcb4cf702601cdeed02b33f9d 100644 (file)
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.31 2010/03/28 09:27:02 sriggs Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.32 2010/04/12 10:40:43 heikki Exp $
  */
 #ifndef XLOG_INTERNAL_H
 #define XLOG_INTERNAL_H
@@ -216,6 +216,9 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
 #define XLogFileName(fname, tli, log, seg) \
    snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg)
 
+#define XLogFromFileName(fname, tli, log, seg) \
+   sscanf(fname, "%08X%08X%08X", tli, log, seg)
+
 #define XLogFilePath(path, tli, log, seg)  \
    snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, log, seg)