pg_archivecleanup: Refactor loop doing old segment removals
authorMichael Paquier <[email protected]>
Wed, 19 Jul 2023 03:23:53 +0000 (12:23 +0900)
committerMichael Paquier <[email protected]>
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  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);
 }