pg_combinebackup: Use new routine to retrieve data of PG_VERSION
authorMichael Paquier <michael@paquier.xyz>
Wed, 15 Oct 2025 00:54:56 +0000 (09:54 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 15 Oct 2025 00:54:56 +0000 (09:54 +0900)
pg_combinebackup's custom logic to retrieve the version number of a data
folder's PG_VERSION can be replaced by the facility introduced in
cd0be131ba6f.  This removes some code.

One thing specific to this tool is that backend versions older than v10
are not supported.  The new code does the same checks as the previous
code.

Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Discussion: https://postgr.es/m/aOiirvWJzwdVCXph@paquier.xyz

src/bin/pg_combinebackup/pg_combinebackup.c

index a330c09d939da138ef91732d49483695f93d04c2..3a325127209216dc24cb86b94b431a0c0c9e17ce 100644 (file)
@@ -34,6 +34,7 @@
 #include "common/relpath.h"
 #include "copy_file.h"
 #include "fe_utils/option_utils.h"
+#include "fe_utils/version.h"
 #include "getopt_long.h"
 #include "lib/stringinfo.h"
 #include "load_manifest.h"
@@ -117,7 +118,6 @@ static void process_directory_recursively(Oid tsoid,
                                          manifest_data **manifests,
                                          manifest_writer *mwriter,
                                          cb_options *opt);
-static int read_pg_version_file(char *directory);
 static void remember_to_cleanup_directory(char *target_path, bool rmtopdir);
 static void reset_directory_cleanup_list(void);
 static cb_tablespace *scan_for_existing_tablespaces(char *pathname,
@@ -153,7 +153,7 @@ main(int argc, char *argv[])
    int         c;
    int         n_backups;
    int         n_prior_backups;
-   int         version;
+   uint32      version;
    uint64      system_identifier;
    char      **prior_backup_dirs;
    cb_options  opt;
@@ -162,6 +162,7 @@ main(int argc, char *argv[])
    StringInfo  last_backup_label;
    manifest_data **manifests;
    manifest_writer *mwriter;
+   char       *pgdata;
 
    pg_logging_init(argv[0]);
    progname = get_progname(argv[0]);
@@ -271,7 +272,12 @@ main(int argc, char *argv[])
    }
 
    /* Read the server version from the final backup. */
-   version = read_pg_version_file(argv[argc - 1]);
+   pgdata = argv[argc - 1];
+   version = get_pg_version(pgdata, NULL);
+   if (GET_PG_MAJORVERSION_NUM(version) < 10)
+       pg_fatal("server version too old");
+   pg_log_debug("read server version %u from file \"%s/%s\"",
+                GET_PG_MAJORVERSION_NUM(version), pgdata, "PG_VERSION");
 
    /* Sanity-check control files. */
    n_backups = argc - optind;
@@ -1155,59 +1161,6 @@ process_directory_recursively(Oid tsoid,
    closedir(dir);
 }
 
-/*
- * Read the version number from PG_VERSION and convert it to the usual server
- * version number format. (e.g. If PG_VERSION contains "14\n" this function
- * will return 140000)
- */
-static int
-read_pg_version_file(char *directory)
-{
-   char        filename[MAXPGPATH];
-   StringInfoData buf;
-   int         fd;
-   int         version;
-   char       *ep;
-
-   /* Construct pathname. */
-   snprintf(filename, MAXPGPATH, "%s/PG_VERSION", directory);
-
-   /* Open file. */
-   if ((fd = open(filename, O_RDONLY, 0)) < 0)
-       pg_fatal("could not open file \"%s\": %m", filename);
-
-   /* Read into memory. Length limit of 128 should be more than generous. */
-   initStringInfo(&buf);
-   slurp_file(fd, filename, &buf, 128);
-
-   /* Close the file. */
-   if (close(fd) != 0)
-       pg_fatal("could not close file \"%s\": %m", filename);
-
-   /* Convert to integer. */
-   errno = 0;
-   version = strtoul(buf.data, &ep, 10);
-   if (errno != 0 || *ep != '\n')
-   {
-       /*
-        * Incremental backup is not relevant to very old server versions that
-        * used multi-part version number (e.g. 9.6, or 8.4). So if we see
-        * what looks like the beginning of such a version number, just bail
-        * out.
-        */
-       if (version < 10 && *ep == '.')
-           pg_fatal("%s: server version too old", filename);
-       pg_fatal("%s: could not parse version number", filename);
-   }
-
-   /* Debugging output. */
-   pg_log_debug("read server version %d from file \"%s\"", version, filename);
-
-   /* Release memory and return result. */
-   pfree(buf.data);
-   return version * 10000;
-}
-
 /*
  * Add a directory to the list of output directories to clean up.
  */