pg_archivecleanup: Refactor loop doing old segment removals
authorMichael Paquier <michael@paquier.xyz>
Wed, 19 Jul 2023 03:23:53 +0000 (12:23 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 19 Jul 2023 03:23:53 +0000 (12:23 +0900)
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

src/bin/pg_archivecleanup/pg_archivecleanup.c

index fc0dca98568b2b77caebdc103601891ed5640254..3533c9b1ab0c2bd0e93b0a0d1d61a168446a2929 100644 (file)
@@ -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);
 }