mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Allow pg_archivecleanup to strip optional file extensions.
Greg Smith and Jaime Casanova, reviewed by Alex Shulgin and myself. e
This commit is contained in:
@ -37,6 +37,7 @@ const char *progname;
|
|||||||
/* Options and defaults */
|
/* Options and defaults */
|
||||||
bool debug = false; /* are we debugging? */
|
bool debug = false; /* are we debugging? */
|
||||||
bool dryrun = false; /* are we performing a dry-run operation? */
|
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 *archiveLocation; /* where to find the archive? */
|
||||||
char *restartWALFileName; /* the file from which we can restart restore */
|
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
|
static void
|
||||||
CleanupPriorWALFiles(void)
|
CleanupPriorWALFiles(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
DIR *xldir;
|
DIR *xldir;
|
||||||
struct dirent *xlde;
|
struct dirent *xlde;
|
||||||
|
char walfile[MAXPGPATH];
|
||||||
|
|
||||||
if ((xldir = opendir(archiveLocation)) != NULL)
|
if ((xldir = opendir(archiveLocation)) != NULL)
|
||||||
{
|
{
|
||||||
while ((xlde = readdir(xldir)) != 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
|
* We ignore the timeline part of the XLOG segment identifiers in
|
||||||
* deciding whether a segment is still needed. This ensures that
|
* 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
|
* file. Note that this means files are not removed in the order
|
||||||
* they were originally written, in case this worries you.
|
* they were originally written, in case this worries you.
|
||||||
*/
|
*/
|
||||||
if (strlen(xlde->d_name) == XLOG_DATA_FNAME_LEN &&
|
if (strlen(walfile) == XLOG_DATA_FNAME_LEN &&
|
||||||
strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_DATA_FNAME_LEN &&
|
strspn(walfile, "0123456789ABCDEF") == XLOG_DATA_FNAME_LEN &&
|
||||||
strcmp(xlde->d_name + 8, exclusiveCleanupFileName + 8) < 0)
|
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",
|
snprintf(WALFilePath, MAXPGPATH, "%s/%s",
|
||||||
archiveLocation, xlde->d_name);
|
archiveLocation, xlde->d_name);
|
||||||
|
|
||||||
@ -167,6 +192,8 @@ SetWALFileNameForCleanup(void)
|
|||||||
{
|
{
|
||||||
bool fnameOK = false;
|
bool fnameOK = false;
|
||||||
|
|
||||||
|
TrimExtension(restartWALFileName, additional_ext);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If restartWALFileName is a WAL file name then just use it directly. If
|
* If restartWALFileName is a WAL file name then just use it directly. If
|
||||||
* restartWALFileName is a .backup filename, make sure we use the prefix
|
* restartWALFileName is a .backup filename, make sure we use the prefix
|
||||||
@ -223,6 +250,7 @@ usage(void)
|
|||||||
printf("\nOptions:\n");
|
printf("\nOptions:\n");
|
||||||
printf(" -d generates debug output (verbose mode)\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(" -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(" --help show this help, then exit\n");
|
||||||
printf(" --version output version information, then exit\n");
|
printf(" --version output version information, then exit\n");
|
||||||
printf("\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)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -269,6 +297,9 @@ main(int argc, char **argv)
|
|||||||
case 'n': /* Dry-Run mode */
|
case 'n': /* Dry-Run mode */
|
||||||
dryrun = true;
|
dryrun = true;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
additional_ext = optarg; /* Extension to remove from xlogfile names */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Try \"%s --help\" for more information.\n", progname);
|
fprintf(stderr, "Try \"%s --help\" for more information.\n", progname);
|
||||||
exit(2);
|
exit(2);
|
||||||
|
@ -107,6 +107,21 @@ pg_archivecleanup: removing file "archive/00000001000000370000000E"
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user