]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
pg_upgrade: Use max_protocol_version=3.0 for older servers
authorJacob Champion <jchampion@postgresql.org>
Tue, 24 Feb 2026 22:01:37 +0000 (14:01 -0800)
committerJacob Champion <jchampion@postgresql.org>
Tue, 24 Feb 2026 22:01:37 +0000 (14:01 -0800)
The grease patch in 4966bd3ed found its first problem: prior to the
February 2018 patch releases, no server knew how to negotiate protocol
versions, so pg_upgrade needs to take that into account when speaking to
those older servers.

This will be true even after the grease feature is reverted; we don't
need anyone to trip over this again in the future. Backpatch so that all
supported versions of pg_upgrade can gracefully handle an update to the
default protocol version. (This is needed for any distributions that
link older binaries against newer libpqs, such as Debian.) Branches
prior to 18 need an additional version check, for the existence of
max_protocol_version.

Per buildfarm member crake.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAOYmi%2B%3D4QhCjssfNEoZVK8LPtWxnfkwT5p-PAeoxtG9gpNjqOQ%40mail.gmail.com
Backpatch-through: 14

src/bin/pg_upgrade/dump.c
src/bin/pg_upgrade/pg_upgrade.h
src/bin/pg_upgrade/server.c
src/bin/pg_upgrade/task.c
src/bin/pg_upgrade/version.c

index e4c9349311a3fb1d3d7f31c789dee1001986d9ce..f47c8d06211f90aaedd8489c095c886c56802597 100644 (file)
@@ -21,9 +21,10 @@ generate_old_dump(void)
 
        /* run new pg_dumpall binary for globals */
        exec_prog(UTILITY_LOG_FILE, NULL, true, true,
-                         "\"%s/pg_dumpall\" %s --globals-only --quote-all-identifiers "
+                         "\"%s/pg_dumpall\" %s%s --globals-only --quote-all-identifiers "
                          "--binary-upgrade %s --no-sync -f \"%s/%s\"",
                          new_cluster.bindir, cluster_conn_opts(&old_cluster),
+                         protocol_negotiation_supported(&old_cluster) ? "" : " -d \"max_protocol_version=3.0\"",
                          log_opts.verbose ? "--verbose" : "",
                          log_opts.dumpdir,
                          GLOBALS_DUMP_FILE);
@@ -43,6 +44,9 @@ generate_old_dump(void)
                initPQExpBuffer(&connstr);
                appendPQExpBufferStr(&connstr, "dbname=");
                appendConnStrVal(&connstr, old_db->db_name);
+               if (!protocol_negotiation_supported(&old_cluster))
+                       appendPQExpBufferStr(&connstr, " max_protocol_version=3.0");
+
                initPQExpBuffer(&escaped_connstr);
                appendShellString(&escaped_connstr, connstr.data);
                termPQExpBuffer(&connstr);
index ec018e4f29297f483dbb76cc5756c2f6808b272a..1d767bbda2df8e94996f83a6b275d8ed1400b48f 100644 (file)
@@ -501,6 +501,7 @@ unsigned int str2uint(const char *str);
 /* version.c */
 
 bool           jsonb_9_4_check_applicable(ClusterInfo *cluster);
+bool           protocol_negotiation_supported(const ClusterInfo *cluster);
 void           old_9_6_invalidate_hash_indexes(ClusterInfo *cluster,
                                                                                        bool check_mode);
 
index eeeac3153f0cf99afffe68a5ac53c147a77d5a23..1eb8bc97c051ea5e952a0bbf9a10c564cf8f79f1 100644 (file)
@@ -71,6 +71,8 @@ get_db_conn(ClusterInfo *cluster, const char *db_name)
                appendPQExpBufferStr(&conn_opts, " host=");
                appendConnStrVal(&conn_opts, cluster->sockdir);
        }
+       if (!protocol_negotiation_supported(cluster))
+               appendPQExpBufferStr(&conn_opts, " max_protocol_version=3.0");
 
        conn = PQconnectdb(conn_opts.data);
        termPQExpBuffer(&conn_opts);
index d4cd487bad0fa6a68177a124b23bfc048d0e722d..3d958527528874ded915d84d82f3d8b45707a535 100644 (file)
@@ -188,6 +188,8 @@ start_conn(const ClusterInfo *cluster, UpgradeTaskSlot *slot)
                appendPQExpBufferStr(&conn_opts, " host=");
                appendConnStrVal(&conn_opts, cluster->sockdir);
        }
+       if (!protocol_negotiation_supported(cluster))
+               appendPQExpBufferStr(&conn_opts, " max_protocol_version=3.0");
 
        slot->conn = PQconnectStart(conn_opts.data);
 
index e709262837e793aadc7f515651ebd93d362b24c5..047670d4acbfc9540893c1f73e903dbafc19cebc 100644 (file)
@@ -28,6 +28,24 @@ jsonb_9_4_check_applicable(ClusterInfo *cluster)
        return false;
 }
 
+/*
+ * Older servers can't support newer protocol versions, so their connection
+ * strings will need to lock max_protocol_version to 3.0.
+ */
+bool
+protocol_negotiation_supported(const ClusterInfo *cluster)
+{
+       /*
+        * The February 2018 patch release (9.3.21, 9.4.16, 9.5.11, 9.6.7, and
+        * 10.2) added support for NegotiateProtocolVersion. But ClusterInfo only
+        * has information about the major version number. To ensure we can still
+        * upgrade older unpatched servers, just assume anything prior to PG11
+        * can't negotiate. It's not possible for those servers to make use of
+        * newer protocols anyway, so nothing is lost.
+        */
+       return (GET_MAJOR_VERSION(cluster->major_version) >= 1100);
+}
+
 /*
  * old_9_6_invalidate_hash_indexes()
  *     9.6 -> 10