pg_createsubscriber: Use new routine to retrieve data of PG_VERSION
authorMichael Paquier <michael@paquier.xyz>
Wed, 15 Oct 2025 02:11:30 +0000 (11:11 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 15 Oct 2025 02:11:30 +0000 (11:11 +0900)
pg_createsubscriber is documented as requiring the same major version as
the target clusters.  Attempting to use this tool on a cluster where the
control file version read does not match with the version compiled with
would lead to the following error message:
pg_createsubscriber: error: control file appears to be corrupt

This is confusing as the control file is correct: only the version
expected does not match.  This commit integrates pg_createsubscriber
with the facility added by cd0be131ba6f, where the contents of
PG_VERSION are read and compared with the value of PG_MAJORVERSION_NUM
expected by the tool.  This puts pg_createsubscriber in line with the
documentation, with a better error message when the version does not
match.

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

src/bin/pg_basebackup/pg_createsubscriber.c

index d29407413d96b2207c78aa825ec1a38b3010d692..9fa5caaf91d67c88f1d553df1adc84b4631d68df 100644 (file)
@@ -26,6 +26,7 @@
 #include "fe_utils/recovery_gen.h"
 #include "fe_utils/simple_list.h"
 #include "fe_utils/string_utils.h"
+#include "fe_utils/version.h"
 #include "getopt_long.h"
 
 #define    DEFAULT_SUB_PORT    "50432"
@@ -407,7 +408,8 @@ static void
 check_data_directory(const char *datadir)
 {
    struct stat statbuf;
-   char        versionfile[MAXPGPATH];
+   uint32      major_version;
+   char       *version_str;
 
    pg_log_info("checking if directory \"%s\" is a cluster data directory",
                datadir);
@@ -420,11 +422,18 @@ check_data_directory(const char *datadir)
            pg_fatal("could not access directory \"%s\": %m", datadir);
    }
 
-   snprintf(versionfile, MAXPGPATH, "%s/PG_VERSION", datadir);
-   if (stat(versionfile, &statbuf) != 0 && errno == ENOENT)
+   /*
+    * Retrieve the contents of this cluster's PG_VERSION.  We require
+    * compatibility with the same major version as the one this tool is
+    * compiled with.
+    */
+   major_version = GET_PG_MAJORVERSION_NUM(get_pg_version(datadir, &version_str));
+   if (major_version != PG_MAJORVERSION_NUM)
    {
-       pg_fatal("directory \"%s\" is not a database cluster directory",
-                datadir);
+       pg_log_error("data directory is of wrong version");
+       pg_log_error_detail("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
+                           "PG_VERSION", version_str, PG_MAJORVERSION);
+       exit(1);
    }
 }