Thread: BackendKeyData is mandatory?

BackendKeyData is mandatory?

From
Tatsuo Ishii
Date:
In the Frontend/Backend protocol, it is explained that after
successful authentication following messages can be sent from backend
to frontend[1]:

BackendKeyData
ParameterStatus
ReadyForQuery
ErrorResponse
NoticeResponse

My question is, BackendKeyData is mandatory or not. Currently
Pgpool-II raises a fatal error if BackendKeyData is not sent before
ReadyForQuery arrives. This is because without the message, frontend
cannot send a CancelRequest message later on, as there's no secret
key.

I heard that some "PostgreSQL compatible" servers do not send
BackendKeyData message to frontend. I wonder if this is a protocol
violation.

[1] https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-START-UP

Best regards,
--
Tatsuo Ishii
SRA OSS K.K.
English: http://www.sraoss.co.jp/index_en/
Japanese:http://www.sraoss.co.jp



Re: BackendKeyData is mandatory?

From
"David G. Johnston"
Date:
On Monday, June 16, 2025, Tatsuo Ishii <ishii@postgresql.org> wrote:

My question is, BackendKeyData is mandatory or not. Currently
Pgpool-II raises a fatal error if BackendKeyData is not sent before
ReadyForQuery arrives. This is because without the message, frontend
cannot send a CancelRequest message later on, as there's no secret
key.

I wouldn’t expect a proxy to make a judgement here; but to simply forward what does show up and otherwise stay silent.  If there is proxy layer code needed to deal with its absence ignoring the cancel attempt with a log warning would be sufficient.  Otherwise, the user has made their choices and this is an optional feature in practice (though resorting to pg_cancel_query make be required for truly hung processes).

David J.

Re: BackendKeyData is mandatory?

From
Tatsuo Ishii
Date:
>> My question is, BackendKeyData is mandatory or not. Currently
>> Pgpool-II raises a fatal error if BackendKeyData is not sent before
>> ReadyForQuery arrives. This is because without the message, frontend
>> cannot send a CancelRequest message later on, as there's no secret
>> key.
> 
> As you say, without BackendKeyData it's impossible to send a query
> cancel, so we expect the server will always send that.

That's my understanding too.

>> I heard that some "PostgreSQL compatible" servers do not send
>> BackendKeyData message to frontend. I wonder if this is a protocol
>> violation.
> 
> I'd say so.  Maybe whoever that is doesn't care to support query
> cancel.  They're within their rights to do that I guess, but
> Pgpool-II does not have to support the case.  (A less incompatible
> way of not supporting query cancel is to send dummy BackendKeyData
> values and then just ignore cancel requests.  So I don't see that
> you need to do anything towards this goal, if it is a goal and
> not merely a broken implementation.)

Agreed.
--
Tatsuo Ishii
SRA OSS K.K.
English: http://www.sraoss.co.jp/index_en/
Japanese:http://www.sraoss.co.jp



Re: BackendKeyData is mandatory?

From
Peter Eisentraut
Date:
On 17.06.25 03:10, Tatsuo Ishii wrote:
> My question is, BackendKeyData is mandatory or not. Currently
> Pgpool-II raises a fatal error if BackendKeyData is not sent before
> ReadyForQuery arrives. This is because without the message, frontend
> cannot send a CancelRequest message later on, as there's no secret
> key.

I think that's fine, if the server does not want to support query 
cancellation.  The current protocol description certainly does not 
support the idea that it is a hard error *not* to send BackendKeyData.

It's also worth thinking about the new protocol 3.2 longer key data.  A 
paranoid server might choose to send key data only if protocol >=3.2 is 
chosen and not if a lower, notionally less secure version is chosen.




Re: BackendKeyData is mandatory?

From
Tatsuo Ishii
Date:
> Or disconnect.

You cannot disconnect without canceling the query at least using psql.
You can kill psql to disconnect but it's possible that the backend
keeps on running the query.

> Or pg_cancel_backend().

In order to issue pg_cancel_backend() the user needs to know the
backend pid which was supposed to be provided by a BackendKeyData
message. Of course you could search and find the backend pid from
other source, but I think it's less user friendly.

>> I would say the server does wrong a decision. I think even if the key
>> is not long, it's still useful than nothing.
> 
> I tend to agree, but people have different priorities. It's also
> reasonable that you'd want to only support long cancellation keys. Or
> maybe you have a proxy that doesn't implement query cancellation, or
> only supports it with long keys because it embeds routing information
> in the key, or something like that.

Agreed. All PostgreSQL "compatible" servers have their own
priority. In Pgpool-II case, the priority is compatibility with
PostgreSQL (I am not saying Pgpool-II is 100% compatible with
PostgreSQL as of today, but it's a implementation limitation which I
want to eliminate someday).

> FWIW my reading of the protocol docs is that BackendKeyData is
> optional.

If majority of developers think so, do we want to update the protocol
docs?  For me the docs is not clear enough.

Best regards,
--
Tatsuo Ishii
SRA OSS K.K.
English: http://www.sraoss.co.jp/index_en/
Japanese:http://www.sraoss.co.jp



Re: BackendKeyData is mandatory?

From
Jelte Fennema-Nio
Date:
On Thu, 19 Jun 2025 at 13:51, Tatsuo Ishii <ishii@postgresql.org> wrote:
> > FWIW my reading of the protocol docs is that BackendKeyData is
> > optional.
>
> If majority of developers think so, do we want to update the protocol
> docs?  For me the docs is not clear enough.

I think the docs currently definitely suggests that BackendKeyData
will always be sent (emphasis mine):

> After having received AuthenticationOk, the frontend must wait for further messages from the server. In this phase a
backendprocess is being started, and the frontend is just an interested bystander. It is still possible for the startup
attemptto fail (ErrorResponse) or the server to decline support for the requested minor protocol version
(NegotiateProtocolVersion),*but in the normal case the backend will send some ParameterStatus messages, BackendKeyData,
andfinally ReadyForQuery.* 

I'd be surprised if many clients handle it correctly if it is not
sent. Looking quickly at the code for pgbouncer and libpq for PG17
(and lower) they definitely don't. They won't throw an error, but
instead of doing nothing when the user tries to cancel a query they
will instead send a cancel message with all zeros to the server. Since
PG18 libpq handles a cancel call nicely as a no-op, when no cancel key
was received.

I agree that it would be good to explicitly call out that the server
not sending BackendKeyData is an option if we don't want the server to
require sending this message.