mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
pg_archivecleanup: Refactor loop doing old segment removals
This commit refactors a bit the main loop of pg_archivecleanup that handles the removal of old segments, reducing by one its level of indentation. This will help an incoming patch that adds a new option related to the segment filtering logic. Author: Atsushi Torikoshi Reviewed-by: Kyotaro Horiguchi, Fujii Masao, Michael Paquier Discussion: https://postgr.es/m/d660ef741ce3d82f3b4283f1cafd576c@oss.nttdata.com
This commit is contained in:
parent
961cf5c905
commit
4a7556f77c
@ -93,75 +93,79 @@ CleanupPriorWALFiles(void)
|
||||
struct dirent *xlde;
|
||||
char walfile[MAXPGPATH];
|
||||
|
||||
if ((xldir = opendir(archiveLocation)) != NULL)
|
||||
xldir = opendir(archiveLocation);
|
||||
if (xldir == NULL)
|
||||
pg_fatal("could not open archive location \"%s\": %m",
|
||||
archiveLocation);
|
||||
|
||||
while (errno = 0, (xlde = readdir(xldir)) != NULL)
|
||||
{
|
||||
while (errno = 0, (xlde = readdir(xldir)) != NULL)
|
||||
char WALFilePath[MAXPGPATH * 2]; /* the file path including
|
||||
* archive */
|
||||
|
||||
/*
|
||||
* Truncation is essentially harmless, because we skip names of length
|
||||
* other than XLOG_FNAME_LEN. (In principle, one could use a
|
||||
* 1000-character additional_ext and get trouble.)
|
||||
*/
|
||||
strlcpy(walfile, xlde->d_name, MAXPGPATH);
|
||||
TrimExtension(walfile, additional_ext);
|
||||
|
||||
/*
|
||||
* Ignore anything does that not look like a WAL segment or a .partial
|
||||
* WAL segment.
|
||||
*/
|
||||
if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We ignore the timeline part of the XLOG segment identifiers in
|
||||
* deciding whether a segment is still needed. This ensures that we
|
||||
* won't prematurely remove a segment from a parent timeline. We could
|
||||
* probably be a little more proactive about removing segments of
|
||||
* non-parent timelines, but that would be a whole lot more
|
||||
* complicated.
|
||||
*
|
||||
* We use the alphanumeric sorting property of the filenames to decide
|
||||
* which ones are earlier than the exclusiveCleanupFileName file. Note
|
||||
* that this means files are not removed in the order they were
|
||||
* originally written, in case this worries you.
|
||||
*/
|
||||
if (strcmp(walfile + 8, exclusiveCleanupFileName + 8) >= 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Use the original file name again now, including any extension that
|
||||
* might have been chopped off before testing the sequence.
|
||||
*/
|
||||
snprintf(WALFilePath, sizeof(WALFilePath), "%s/%s",
|
||||
archiveLocation, xlde->d_name);
|
||||
|
||||
if (dryrun)
|
||||
{
|
||||
/*
|
||||
* Truncation is essentially harmless, because we skip names of
|
||||
* length other than XLOG_FNAME_LEN. (In principle, one could use
|
||||
* a 1000-character additional_ext and get trouble.)
|
||||
* Prints the name of the file to be removed and skips the actual
|
||||
* removal. The regular printout is so that the user can pipe the
|
||||
* output into some other program.
|
||||
*/
|
||||
strlcpy(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
|
||||
* we won't prematurely remove a segment from a parent timeline.
|
||||
* We could probably be a little more proactive about removing
|
||||
* segments of non-parent timelines, but that would be a whole lot
|
||||
* more complicated.
|
||||
*
|
||||
* We use the alphanumeric sorting property of the filenames to
|
||||
* decide which ones are earlier than the exclusiveCleanupFileName
|
||||
* file. Note that this means files are not removed in the order
|
||||
* they were originally written, in case this worries you.
|
||||
*/
|
||||
if ((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) &&
|
||||
strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0)
|
||||
{
|
||||
char WALFilePath[MAXPGPATH * 2]; /* the file path
|
||||
* including archive */
|
||||
|
||||
/*
|
||||
* Use the original file name again now, including any
|
||||
* extension that might have been chopped off before testing
|
||||
* the sequence.
|
||||
*/
|
||||
snprintf(WALFilePath, sizeof(WALFilePath), "%s/%s",
|
||||
archiveLocation, xlde->d_name);
|
||||
|
||||
if (dryrun)
|
||||
{
|
||||
/*
|
||||
* Prints the name of the file to be removed and skips the
|
||||
* actual removal. The regular printout is so that the
|
||||
* user can pipe the output into some other program.
|
||||
*/
|
||||
printf("%s\n", WALFilePath);
|
||||
pg_log_debug("file \"%s\" would be removed", WALFilePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
pg_log_debug("removing file \"%s\"", WALFilePath);
|
||||
|
||||
rc = unlink(WALFilePath);
|
||||
if (rc != 0)
|
||||
pg_fatal("could not remove file \"%s\": %m",
|
||||
WALFilePath);
|
||||
}
|
||||
printf("%s\n", WALFilePath);
|
||||
pg_log_debug("file \"%s\" would be removed", WALFilePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno)
|
||||
pg_fatal("could not read archive location \"%s\": %m",
|
||||
archiveLocation);
|
||||
if (closedir(xldir))
|
||||
pg_fatal("could not close archive location \"%s\": %m",
|
||||
archiveLocation);
|
||||
pg_log_debug("removing file \"%s\"", WALFilePath);
|
||||
|
||||
rc = unlink(WALFilePath);
|
||||
if (rc != 0)
|
||||
pg_fatal("could not remove file \"%s\": %m",
|
||||
WALFilePath);
|
||||
}
|
||||
else
|
||||
pg_fatal("could not open archive location \"%s\": %m",
|
||||
|
||||
if (errno)
|
||||
pg_fatal("could not read archive location \"%s\": %m",
|
||||
archiveLocation);
|
||||
if (closedir(xldir))
|
||||
pg_fatal("could not close archive location \"%s\": %m",
|
||||
archiveLocation);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user