Skip to content

Commit 4a7556f

Browse files
committed
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/[email protected]
1 parent 961cf5c commit 4a7556f

File tree

1 file changed

+66
-62
lines changed

1 file changed

+66
-62
lines changed

src/bin/pg_archivecleanup/pg_archivecleanup.c

Lines changed: 66 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -93,75 +93,79 @@ CleanupPriorWALFiles(void)
9393
struct dirent *xlde;
9494
char walfile[MAXPGPATH];
9595

96-
if ((xldir = opendir(archiveLocation)) != NULL)
96+
xldir = opendir(archiveLocation);
97+
if (xldir == NULL)
98+
pg_fatal("could not open archive location \"%s\": %m",
99+
archiveLocation);
100+
101+
while (errno = 0, (xlde = readdir(xldir)) != NULL)
97102
{
98-
while (errno = 0, (xlde = readdir(xldir)) != NULL)
103+
char WALFilePath[MAXPGPATH * 2]; /* the file path including
104+
* archive */
105+
106+
/*
107+
* Truncation is essentially harmless, because we skip names of length
108+
* other than XLOG_FNAME_LEN. (In principle, one could use a
109+
* 1000-character additional_ext and get trouble.)
110+
*/
111+
strlcpy(walfile, xlde->d_name, MAXPGPATH);
112+
TrimExtension(walfile, additional_ext);
113+
114+
/*
115+
* Ignore anything does that not look like a WAL segment or a .partial
116+
* WAL segment.
117+
*/
118+
if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile))
119+
continue;
120+
121+
/*
122+
* We ignore the timeline part of the XLOG segment identifiers in
123+
* deciding whether a segment is still needed. This ensures that we
124+
* won't prematurely remove a segment from a parent timeline. We could
125+
* probably be a little more proactive about removing segments of
126+
* non-parent timelines, but that would be a whole lot more
127+
* complicated.
128+
*
129+
* We use the alphanumeric sorting property of the filenames to decide
130+
* which ones are earlier than the exclusiveCleanupFileName file. Note
131+
* that this means files are not removed in the order they were
132+
* originally written, in case this worries you.
133+
*/
134+
if (strcmp(walfile + 8, exclusiveCleanupFileName + 8) >= 0)
135+
continue;
136+
137+
/*
138+
* Use the original file name again now, including any extension that
139+
* might have been chopped off before testing the sequence.
140+
*/
141+
snprintf(WALFilePath, sizeof(WALFilePath), "%s/%s",
142+
archiveLocation, xlde->d_name);
143+
144+
if (dryrun)
99145
{
100146
/*
101-
* Truncation is essentially harmless, because we skip names of
102-
* length other than XLOG_FNAME_LEN. (In principle, one could use
103-
* a 1000-character additional_ext and get trouble.)
147+
* Prints the name of the file to be removed and skips the actual
148+
* removal. The regular printout is so that the user can pipe the
149+
* output into some other program.
104150
*/
105-
strlcpy(walfile, xlde->d_name, MAXPGPATH);
106-
TrimExtension(walfile, additional_ext);
107-
108-
/*
109-
* We ignore the timeline part of the XLOG segment identifiers in
110-
* deciding whether a segment is still needed. This ensures that
111-
* we won't prematurely remove a segment from a parent timeline.
112-
* We could probably be a little more proactive about removing
113-
* segments of non-parent timelines, but that would be a whole lot
114-
* more complicated.
115-
*
116-
* We use the alphanumeric sorting property of the filenames to
117-
* decide which ones are earlier than the exclusiveCleanupFileName
118-
* file. Note that this means files are not removed in the order
119-
* they were originally written, in case this worries you.
120-
*/
121-
if ((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) &&
122-
strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0)
123-
{
124-
char WALFilePath[MAXPGPATH * 2]; /* the file path
125-
* including archive */
126-
127-
/*
128-
* Use the original file name again now, including any
129-
* extension that might have been chopped off before testing
130-
* the sequence.
131-
*/
132-
snprintf(WALFilePath, sizeof(WALFilePath), "%s/%s",
133-
archiveLocation, xlde->d_name);
134-
135-
if (dryrun)
136-
{
137-
/*
138-
* Prints the name of the file to be removed and skips the
139-
* actual removal. The regular printout is so that the
140-
* user can pipe the output into some other program.
141-
*/
142-
printf("%s\n", WALFilePath);
143-
pg_log_debug("file \"%s\" would be removed", WALFilePath);
144-
continue;
145-
}
146-
147-
pg_log_debug("removing file \"%s\"", WALFilePath);
148-
149-
rc = unlink(WALFilePath);
150-
if (rc != 0)
151-
pg_fatal("could not remove file \"%s\": %m",
152-
WALFilePath);
153-
}
151+
printf("%s\n", WALFilePath);
152+
pg_log_debug("file \"%s\" would be removed", WALFilePath);
153+
continue;
154154
}
155155

156-
if (errno)
157-
pg_fatal("could not read archive location \"%s\": %m",
158-
archiveLocation);
159-
if (closedir(xldir))
160-
pg_fatal("could not close archive location \"%s\": %m",
161-
archiveLocation);
156+
pg_log_debug("removing file \"%s\"", WALFilePath);
157+
158+
rc = unlink(WALFilePath);
159+
if (rc != 0)
160+
pg_fatal("could not remove file \"%s\": %m",
161+
WALFilePath);
162162
}
163-
else
164-
pg_fatal("could not open archive location \"%s\": %m",
163+
164+
if (errno)
165+
pg_fatal("could not read archive location \"%s\": %m",
166+
archiveLocation);
167+
if (closedir(xldir))
168+
pg_fatal("could not close archive location \"%s\": %m",
165169
archiveLocation);
166170
}
167171

0 commit comments

Comments
 (0)