On Fri, Mar 9, 2012 at 12:46 AM, Jaime Casanova <[email protected]> wrote:
> On Thu, Mar 8, 2012 at 8:25 AM, Robert Haas <[email protected]> wrote:
>> On Sun, Feb 12, 2012 at 9:19 PM, Greg Smith <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers