pg_checksums: Use new routine to retrieve data of PG_VERSION
authorMichael Paquier <michael@paquier.xyz>
Mon, 20 Oct 2025 00:35:22 +0000 (09:35 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 20 Oct 2025 00:35:22 +0000 (09:35 +0900)
Previously, attempting to use pg_checksums on a cluster with a control
file whose version does not match with what thetool is able to support
would lead to the following error:
pg_checksums: error: pg_control CRC value is incorrect

This is confusing, because it would look like the control file is
corrupted.  However, the contents of the control file are correct,
pg_checksums not being able to understand how the past control file is
shaped.

This commit adds a check based on PG_VERSION, using the facility added
by cd0be131ba6f, using the same error message as some of the other
frontend tools.  A note is added in the documentation about the major
version requirement.

Author: Michael Banck <mbanck@gmx.net>
Discussion: https://postgr.es/m/68f1ff21.170a0220.2c9b5f.4df5@mx.google.com

doc/src/sgml/ref/pg_checksums.sgml
src/bin/pg_checksums/pg_checksums.c

index 95043aa329c020937936851500c95dd0ad97639c..e9e393495dfc7c50079399b4e9d60b2ae6915049 100644 (file)
@@ -247,5 +247,9 @@ PostgreSQL documentation
    remains unchanged, and <application>pg_checksums</application> can be
    re-run to perform the same operation.
   </para>
+  <para>
+   The target cluster must have the same major version as
+   <application>pg_checksums</application>.
+  </para>
  </refsect1>
 </refentry>
index f20be82862a2b769068a3e0ea7326474fde0755c..46cb2f36efaa5d1cc5b630f975d6f4f682f8c6c8 100644 (file)
@@ -25,6 +25,7 @@
 #include "common/logging.h"
 #include "common/relpath.h"
 #include "fe_utils/option_utils.h"
+#include "fe_utils/version.h"
 #include "getopt_long.h"
 #include "pg_getopt.h"
 #include "storage/bufpage.h"
@@ -448,6 +449,8 @@ main(int argc, char *argv[])
    int         c;
    int         option_index;
    bool        crc_ok;
+   uint32      major_version;
+   char       *version_str;
 
    pg_logging_init(argv[0]);
    set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_checksums"));
@@ -543,6 +546,20 @@ main(int argc, char *argv[])
        exit(1);
    }
 
+   /*
+    * 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_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);
+   }
+
    /* Read the control file and check compatibility */
    ControlFile = get_controlfile(DataDir, &crc_ok);
    if (!crc_ok)