On Fri, Mar 9, 2012 at 12:46 AM, Jaime Casanova <ja...@2ndquadrant.com> wrote: > On Thu, Mar 8, 2012 at 8:25 AM, Robert Haas <robertmh...@gmail.com> wrote: >> On Sun, Feb 12, 2012 at 9:19 PM, Greg Smith <g...@2ndquadrant.com> wrote: >>> The smaller step of automatically stripping the specified suffix from the >>> input file name, when it matches the one we've told the program to expect, >>> seems like a usability improvement unlikely to lead to bad things though. >>> I've certainly made the mistake you've shown when using the patched version >>> of the program myself, just didn't think about catching and correcting it >>> myself before. We can rev this to add that feature and resubmit easily >>> enough, will turn that around soon. >> >> This change seems plenty small enough to slip in even at this late >> date, but I guess we're lacking a new version of the patch. >> > > Sorry, here's the patch rebased and with the suggestion from Alex. > Which reminds me, I never thank him for the review (shame on me) :D >
with the patch this time -- Jaime Casanova www.2ndQuadrant.com Professional PostgreSQL: Soporte 24x7 y capacitación
diff --git a/contrib/pg_archivecleanup/pg_archivecleanup.c b/contrib/pg_archivecleanup/pg_archivecleanup.c new file mode 100644 index adfc83d..8f6ca2c *** a/contrib/pg_archivecleanup/pg_archivecleanup.c --- b/contrib/pg_archivecleanup/pg_archivecleanup.c *************** const char *progname; *** 37,42 **** --- 37,43 ---- /* 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 */ *************** static void *** 94,106 **** --- 95,136 ---- CleanupPriorWALFiles(void) { int rc; + int chop_at; DIR *xldir; struct dirent *xlde; + char walfile[MAXPGPATH]; if ((xldir = opendir(archiveLocation)) != NULL) { while ((xlde = readdir(xldir)) != NULL) { + strncpy(walfile, xlde->d_name, MAXPGPATH); + /* + * Remove any specified additional extension from the filename + * before testing it against the conditions below. + */ + if (additional_ext) + { + chop_at = strlen(walfile) - strlen(additional_ext); + /* + * Only chop if this is long enough to be a file name and the + * extension matches. + */ + if ((chop_at >= (XLOG_DATA_FNAME_LEN - 1)) && + (strcmp(walfile + chop_at,additional_ext)==0)) + { + walfile[chop_at] = '\0'; + /* + * This is too chatty even for regular debug output, but + * leaving it in for program testing. + */ + if (false) + fprintf(stderr, + "removed extension='%s' from file=%s result=%s\n", + additional_ext,xlde->d_name,walfile); + } + } + /* * We ignore the timeline part of the XLOG segment identifiers in * deciding whether a segment is still needed. This ensures that *************** CleanupPriorWALFiles(void) *** 114,123 **** * 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) { snprintf(WALFilePath, MAXPGPATH, "%s/%s", archiveLocation, xlde->d_name); --- 144,157 ---- * file. Note that this means files are not removed in the order * they were originally written, in case this worries you. */ ! 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); *************** SetWALFileNameForCleanup(void) *** 167,172 **** --- 201,228 ---- { bool fnameOK = false; + /* if restartWALFileName was specified with an extension remove it first */ + if (additional_ext) + { + int max_len = 0; /* Initialize just to keep quiet the compiler */ + int chop_at = strlen(restartWALFileName) - strlen(additional_ext); + + if (strlen(restartWALFileName) == (XLOG_DATA_FNAME_LEN + strlen(additional_ext))) + max_len = XLOG_DATA_FNAME_LEN; + else if (strlen(restartWALFileName) == (XLOG_BACKUP_FNAME_LEN + strlen(additional_ext) + 1)) + max_len = XLOG_BACKUP_FNAME_LEN; + + /* + * Only chop if this is long enough to be a file name and the + * extension matches. + */ + if ((chop_at >= (max_len - 1)) && + (strcmp(restartWALFileName + chop_at, additional_ext)==0)) + { + restartWALFileName[chop_at] = '\0'; + } + } + /* * If restartWALFileName is a WAL file name then just use it directly. If * restartWALFileName is a .backup filename, make sure we use the prefix *************** usage(void) *** 223,228 **** --- 279,285 ---- 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" *************** main(int argc, char **argv) *** 259,265 **** } } ! while ((c = getopt(argc, argv, "dn")) != -1) { switch (c) { --- 316,322 ---- } } ! while ((c = getopt(argc, argv, "x:dn")) != -1) { switch (c) { *************** main(int argc, char **argv) *** 269,274 **** --- 326,334 ---- 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); diff --git a/doc/src/sgml/pgarchivecleanup.sgml b/doc/src/sgml/pgarchivecleanup.sgml new file mode 100644 index 8148c53..40bac85 *** a/doc/src/sgml/pgarchivecleanup.sgml --- b/doc/src/sgml/pgarchivecleanup.sgml *************** pg_archivecleanup: removing file "archi *** 107,112 **** --- 107,127 ---- </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>
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers