Allow pg_archivecleanup to strip optional file extensions.
authorRobert Haas <rhaas@postgresql.org>
Thu, 5 Apr 2012 18:18:42 +0000 (14:18 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 5 Apr 2012 18:18:42 +0000 (14:18 -0400)
Greg Smith and Jaime Casanova, reviewed by Alex Shulgin and myself.
e

contrib/pg_archivecleanup/pg_archivecleanup.c
doc/src/sgml/pgarchivecleanup.sgml

index adfc83dea70eca52beebcd73e53f061161a1b300..1b3cecf3c44c13c7e020dec2358102df83bcc4f1 100644 (file)
@@ -37,6 +37,7 @@ const char *progname;
 /* Options and defaults */
 bool           debug = false;          /* are we debugging? */
 bool           dryrun = false;         /* are we performing a dry-run operation? */
+char      *additional_ext = NULL;      /* Extension to remove from filenames */
 
 char      *archiveLocation;    /* where to find the archive? */
 char      *restartWALFileName; /* the file from which we can restart restore */
@@ -90,17 +91,37 @@ Initialize(void)
        }
 }
 
+static void
+TrimExtension(char *filename, char *extension)
+{
+       int                     flen;
+       int                     elen;
+
+       if (extension == NULL)
+               return;
+
+       elen = strlen(extension);
+       flen = strlen(filename);
+
+       if (flen > elen && strcmp(filename + flen - elen, extension) == 0)
+               filename[flen - elen] = '\0';
+}
+
 static void
 CleanupPriorWALFiles(void)
 {
        int                     rc;
        DIR                *xldir;
        struct dirent *xlde;
+       char            walfile[MAXPGPATH];
 
        if ((xldir = opendir(archiveLocation)) != NULL)
        {
                while ((xlde = readdir(xldir)) != NULL)
                {
+                       strncpy(walfile, xlde->d_name, MAXPGPATH);
+                       TrimExtension(walfile, additional_ext);
+
                        /*
                         * We ignore the timeline part of the XLOG segment identifiers in
                         * deciding whether a segment is still needed.  This ensures that
@@ -114,10 +135,14 @@ CleanupPriorWALFiles(void)
                         * file. Note that this means files are not removed in the order
                         * they were originally written, in case this worries you.
                         */
-                       if (strlen(xlde->d_name) == XLOG_DATA_FNAME_LEN &&
-                       strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_DATA_FNAME_LEN &&
-                               strcmp(xlde->d_name + 8, exclusiveCleanupFileName + 8) < 0)
+                       if (strlen(walfile) == XLOG_DATA_FNAME_LEN &&
+                       strspn(walfile, "0123456789ABCDEF") == XLOG_DATA_FNAME_LEN &&
+                               strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0)
                        {
+                               /* 
+                                * Use the original file name again now, including any extension
+                                * that might have been chopped off before testing the sequence.
+                                */
                                snprintf(WALFilePath, MAXPGPATH, "%s/%s",
                                                 archiveLocation, xlde->d_name);
 
@@ -167,6 +192,8 @@ SetWALFileNameForCleanup(void)
 {
        bool            fnameOK = false;
 
+       TrimExtension(restartWALFileName, additional_ext);
+
        /*
         * If restartWALFileName is a WAL file name then just use it directly. If
         * restartWALFileName is a .backup filename, make sure we use the prefix
@@ -223,6 +250,7 @@ usage(void)
        printf("\nOptions:\n");
        printf("  -d                 generates debug output (verbose mode)\n");
        printf("  -n                 shows the names of the files that would have been removed (dry-run)\n");
+       printf("  -x EXT             cleanup files if they have this same extension\n");
        printf("  --help             show this help, then exit\n");
        printf("  --version          output version information, then exit\n");
        printf("\n"
@@ -259,7 +287,7 @@ main(int argc, char **argv)
                }
        }
 
-       while ((c = getopt(argc, argv, "dn")) != -1)
+       while ((c = getopt(argc, argv, "x:dn")) != -1)
        {
                switch (c)
                {
@@ -269,6 +297,9 @@ main(int argc, char **argv)
                        case 'n':                       /* Dry-Run mode */
                                dryrun = true;
                                break;
+                       case 'x':
+                               additional_ext = optarg; /* Extension to remove from xlogfile names */
+                               break;
                        default:
                                fprintf(stderr, "Try \"%s --help\" for more information.\n", progname);
                                exit(2);
index 8148c53d3a0a591f8912fa0a2180a4df4bc0333d..40bac8547003043b7c68f47c4e238487e55f7e42 100644 (file)
@@ -107,6 +107,21 @@ pg_archivecleanup:  removing file "archive/00000001000000370000000E"
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>-x</option> <replaceable>extension</></term>
+      <listitem>
+       <para>
+        When using the program as a standalone utility, provide an extension
+        that will be stripped from all file names before deciding if they
+        should be deleted.  This is typically useful for cleaning up archives
+        that have been compressed during storage, and therefore have had an
+        extension added by the compression program.  Note that the
+        <filename>.backup</> file name passed to the program should not
+        include the extension.
+       </para>
+      </listitem>
+     </varlistentry>
+
     </variablelist>
    </para>