Re: protocol version negotiation (Re: Libpq PGRES_COPY_BOTH - version compatibility)

From: Craig Ringer <craig(at)2ndquadrant(dot)com>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Peter Eisentraut <peter_e(at)gmx(dot)net>, Magnus Hagander <magnus(at)hagander(dot)net>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: protocol version negotiation (Re: Libpq PGRES_COPY_BOTH - version compatibility)
Date: 2017-06-29 01:44:44
Message-ID: CAMsr+YFnhHUnq+fbWshkudwO4WhgeCyodULVpBNdbzzgn8EXMw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 29 June 2017 at 03:01, Robert Haas <robertmhaas(at)gmail(dot)com> wrote:

> One problem with that is that it means that the format of the
> StartupMessage itself can never change, which I think is not a good
> choice.

The startup message could be immediately followed by another
supplemental message, though.

- Startup["Protocol 3.2"]
- Extra Info Message

A server that only knows protocol version 3.1 would read the 3.1
message and reply with a NegotiateProtocolVersion or whatever, then
*discard all messages until it sees a new startup message*, so it
wouldn't be upset. Quite like what we do when reading until Sync after
an error.

Existing servers would bounce the connection when they saw the 3.2
field and the client would have to reconnect with 3.0. But we could
possibly even backpatch the nicer behaviour, since it's simple and
will only ever come into effect when sent a higher protocol version
msg that no existing client generates.

If we ever landed up wanting to greatly revise the startup message
down the track, we could land up sending a stub startup message with
protocol 3.4 or whatever that just tells aware servers "real startup
message follows". Bit of a waste, but not that bad given how expensive
connections are. A dummy startup message is quite small.

I don't have a strong opinion here, just raising the possibility that
not being able to vary the startup message format may not be the end
of the world.

> If, for example, we want to add a new option to the startup
> message (aside from the existing user, database, options, and
> replication keywords), we really can't do that today.

Right. An obvious example would be to put a starttls-like request in
it, asking the server to initiate TLS negotiation if supported.

Or an option asking the server to determine the DB to connect to based
on some property of the user.

Similarly, I've repeatedly wanted ways to specify client support for /
requests for optional protocol messages, like sending the xid and
commit record lsn of a commit along with the commit message.

Both those could be done in immediate follow-up messages, though. I
can't personally think of much right away that wouldn't work pretty
well in a follow-on message. There's a small one-off protocol size
overhead with doing it that way, but no extra latency, so who cares?

> It wouldn't be
> so bad if unrecognized parameters were just ignored; the client would
> know from the ServerProtocolVersion (or ParameterStatus) message that
> server had ignored those options and could respond as it saw fit.

Yeah. In retrospect it's a pity the key/value pairs don't come with
some kind of optional/required flag so the client can say "error if
you don't understand this, it's important" or "I don't care if you
don't understand this, and I'll notice when you fail to GUC_REPORT it
back to me". Or some convention like underscore-prefixing for
optional.

>> It's possible that we should do something that's not based on just a
>> linear protocol version number, but instead involves some kind of
>> bitmask of capabilities, say. So the ServerProtocolVersion message
>> maybe needs to be a bit more complicated, and if the client does get
>> one back, maybe it should forward a ClientProtocolVersion message with
>> its own bitmask. But these things could be designed in detail later.
>
> Right. So for example we could decide that any parameter names that
> are passed in the startup packet that begin with an underscore are not
> GUCs but some kind of protocol extension; the server replies with some
> message containing a list of the ones which were not understood.

There's a *lot* of value to that idea when you consider proxies like
PgPool-II and PgBouncer that may struggle to satisfy all capabilities
of some protocol 3.3 but want to offer some key parts of it.

There's a price in terms of complexity but probably not a big one.
Some places that would be "client protocol version >= 3.3" would
instead be "client has_capability(x)". Possibly cleaner to read even
if we _did_ use a linear protocol version, frankly.

Also, importantly in my opinion, this would let clients turn things
on/off easily. I badly want this myself, as I really want the server
to be able to reply to each COMMIT with an extended CommandComplete
message or extra-info message after it, containing the commit record
LSN. Similarly, I really want to be able to send the xid of an xact on
the wire when one is assigned to an xact. Many clients won't need,
want or understand these things and whether they're protocol 3.0 or
3.9 they can just not ask for them.

Capabilities will make startup messages bigger. Personally I don't
care much about that, as on modern networks it's all about latency not
message size. We'd use abbreviated capability names I expect. If the
list gets too big we could always roll up capabilities that have
become universally adopted into the next protocol version bump so it's
assumed that a client announcing proto 3.3 supports feature x and
doesn't need to list it.

--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2017-06-29 01:49:09 Re: What does it mean by XLOG_BACKUP_RECORD?
Previous Message Masahiko Sawada 2017-06-29 01:28:21 What does it mean by XLOG_BACKUP_RECORD?