]> 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:41 +0000 (14:01 -0800)
committerJacob Champion <jchampion@postgresql.org>
Tue, 24 Feb 2026 22:01:41 +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 55f6e7b4d9c3e2715428302f70d4775206437216..806bf3bef97a7365d890ba6cd42b707c74e89b52 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 69c965bb7d09abc5fb80013dfbb251786966b4fb..22057c229010a22c31babd660902cd8eb996fae5 100644 (file)
@@ -493,6 +493,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 7eb15bc7d5acc6f97f6e3b9c929503d19ed3b38c..43e6797e14c1a689366b2c60fb35581d4a97edcd 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 ee0e24571521590dc749784ecd3cb71941d35e62..a19ea8445a0985f06d6a237b716fd965e2bad42c 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 3ad5a991a30ea39c87ca1119220c1e550c19d307..56f3dc693fb14b8b522a4bd281d93b0efe39a845 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