public inbox for [email protected]  
help / color / mirror / Atom feed
From: Jacob Champion <[email protected]>
To: Tom Lane <[email protected]>
Cc: Jelte Fennema-Nio <[email protected]>
Cc: [email protected]
Cc: Andrew Dunstan <[email protected]>
Subject: Re: pgsql: libpq: Grease the protocol by default
Date: Tue, 24 Feb 2026 09:18:19 -0800
Message-ID: <CAOYmi+=96EGcQnY2w99yLeARHsbvgT_2Bv1hjXKUziykMzMhtA@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
	<CAOYmi+=4QhCjssfNEoZVK8LPtWxnfkwT5p-PAeoxtG9gpNjqOQ@mail.gmail.com>
	<[email protected]>
	<CAOYmi+k8ENYkErqSEYEqW39YWPfe_ii7g5Acm1c9asNuRMriNg@mail.gmail.com>
	<[email protected]>
	<CAOYmi+mtFBsB2zePSvbpa-2Zb-+V5bov_t2BzkGH7vfKX0ny_w@mail.gmail.com>
	<[email protected]>
	<CAOYmi+kC3AN0QJKT0OunHCmi4UU7-15eu7w-DY5ckOgHiQE1QA@mail.gmail.com>
	<[email protected]>

On Mon, Feb 23, 2026 at 6:08 PM Tom Lane <[email protected]> wrote:
> Jacob Champion <[email protected]> writes:
> > On Mon, Feb 23, 2026 at 4:45 PM Tom Lane <[email protected]> wrote:
> >> Also: I was initially baffled why you thought this needs
> >> back-patching, but I guess you have one eye on packagers like
> >> Debian who think they can make older versions use newer libpq.so.
>
> > Right.
>
> Actually, that is going to be harder than you thought, because libpq
> before v18 will spit up on connection option "max_protocol_version".

Ha, right. Luckily the failure is very loud when testing :)

> Fortunately, we long ago had the foresight to invent PQlibVersion,
> so you could make addition of the extra option conditional on
> PQlibVersion(conn) >= 180000 in branches before 18.

Attached is a sample backport for REL_14_STABLE, using that strategy.
Tested with pg_upgrade 9.2-to-14, when linked against both 14.22 and
HEAD versions of libpq. I still need to run a sanity check with the
other 9.x lines to make sure I've selected the right cutoffs.

> Yeah, I came to the same conclusion.  I got a clean BF run using
> your patch together with the attached patch for the BF client.

Nice, thanks!

--Jacob


Attachments:

  [application/octet-stream] 0001-pg_upgrade-Use-max_protocol_version-3.0-for-older-se.14.patch (5.1K, 2-0001-pg_upgrade-Use-max_protocol_version-3.0-for-older-se.14.patch)
  download | inline diff:
From b0a0c381ab83ee39b71c296d367eb06e23569aa5 Mon Sep 17 00:00:00 2001
From: Jacob Champion <[email protected]>
Date: Mon, 23 Feb 2026 15:28:32 -0800
Subject: [PATCH] pg_upgrade: Use max_protocol_version=3.0 for older servers

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.

Discussion: https://postgr.es/m/CAOYmi%2B%3D4QhCjssfNEoZVK8LPtWxnfkwT5p-PAeoxtG9gpNjqOQ%40mail.gmail.com
Backpatch-through: 14
---
 src/bin/pg_upgrade/pg_upgrade.h |  1 +
 src/bin/pg_upgrade/dump.c       |  6 +++++-
 src/bin/pg_upgrade/server.c     |  2 ++
 src/bin/pg_upgrade/version.c    | 37 +++++++++++++++++++++++++++++++++
 4 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index e647e71ecaf..14f9cb522db 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -446,6 +446,7 @@ bool		check_for_data_types_usage(ClusterInfo *cluster,
 bool		check_for_data_type_usage(ClusterInfo *cluster,
 									  const char *type_name,
 									  const char *output_path);
+bool		protocol_negotiation_supported(const ClusterInfo *cluster);
 void		new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster,
 													 bool check_mode);
 void		old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster);
diff --git a/src/bin/pg_upgrade/dump.c b/src/bin/pg_upgrade/dump.c
index 90060d0f8eb..ee0ace082ca 100644
--- a/src/bin/pg_upgrade/dump.c
+++ b/src/bin/pg_upgrade/dump.c
@@ -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 -f %s",
 			  new_cluster.bindir, cluster_conn_opts(&old_cluster),
+			  protocol_negotiation_supported(&old_cluster) ? "" : " -d \"max_protocol_version=3.0\"",
 			  log_opts.verbose ? "--verbose" : "",
 			  GLOBALS_DUMP_FILE);
 	check_ok();
@@ -42,6 +43,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);
diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c
index 7fed0ae1086..f49f3013c38 100644
--- a/src/bin/pg_upgrade/server.c
+++ b/src/bin/pg_upgrade/server.c
@@ -70,6 +70,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);
diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c
index ccb012657be..fdddd90bf97 100644
--- a/src/bin/pg_upgrade/version.c
+++ b/src/bin/pg_upgrade/version.c
@@ -325,6 +325,43 @@ old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
 		check_ok();
 }
 
+/*
+ * 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)
+{
+	int			major = GET_MAJOR_VERSION(cluster->major_version);
+
+	/*
+	 * Back-branch-specific complication: for libpq versions prior to PG18,
+	 * max_protocol_version isn't supported. But we also don't need to worry
+	 * about newer protocol versions being used in that case, so just lie and
+	 * return true.
+	 *
+	 * (Checking for a libpq version that's newer than this branch looks very
+	 * strange, but distributions are allowed to link older pg_upgrade
+	 * binaries against the newest release of libpq.)
+	 */
+	if (PQlibVersion() < 180000)
+		return true;
+
+	/*
+	 * These version numbers come from the February 2018 patch release, which
+	 * added support for NegotiateProtocolVersion: 9.3.21, 9.4.16, 9.5.11,
+	 * 9.6.7, and 10.2.
+	 */
+	if (cluster->major_version < 90321
+		|| (major == 904 && cluster->major_version < 90416)
+		|| (major == 905 && cluster->major_version < 90511)
+		|| (major == 906 && cluster->major_version < 90607)
+		|| (major == 1000 && cluster->major_version < 100002))
+		return false;
+
+	return true;
+}
+
 /*
  * old_9_6_invalidate_hash_indexes()
  *	9.6 -> 10
-- 
2.34.1



view thread (27+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: pgsql: libpq: Grease the protocol by default
  In-Reply-To: <CAOYmi+=96EGcQnY2w99yLeARHsbvgT_2Bv1hjXKUziykMzMhtA@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox