Re: BackendKeyData is mandatory?
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Jelte Fennema-Nio <postgres@jeltef.nl>,
Jacob Champion <jacob.champion@enterprisedb.com>
Cc: Tatsuo Ishii <ishii@postgresql.org>, tgl@sss.pgh.pa.us,
peter@eisentraut.org, pgsql-hackers@postgresql.org,
Dave Cramer <davecramer@gmail.com>
Date: 2025-07-29T20:41:57Z
Lists: pgsql-hackers
Thanks for digging into this! On 03/07/2025 09:13, Jelte Fennema-Nio wrote: > On Thu Jul 3, 2025 at 2:03 AM CEST, Jacob Champion wrote: >> On Wed, Jul 2, 2025 at 3:18 PM Jelte Fennema-Nio <postgres@jeltef.nl> >> wrote: >> I will hold off on detailed review until Heikki gives an opinion on >> the design (or we get closer to the end of the month), to avoid making >> busy work for you -- but I will say that I think you need to prove >> that the new `failure:` case in getBackendKeyData() is safe, because I >> don't think any of the other failure modes behave that way inside >> pqParseInput3(). > > I changed it slightly now to align with the handleSyncLoss function its > implementation. To recap, there is a concrete problem with psycopg2 and libpq v18: if the server doesn't end BackendKeyData, the connection fails with "can't get cancellation key" error. With previous versions, it worked, and if you actually try to cancel, it will send a bogus cancellation message with all-zeros key and pid. psycopg3 works better. It only calls PQgetCancel() when actually cancelling. So you can connect, and only if try to actually cancel, you get a "couldn't create cancel object" error. That seems quite reasonable. I think agree with the changes to PQgetCancel()/PQcancel(). It fixes psycopg2. I don't see any nicer way to signal that cancellation is not available with PQgetCancel(). New applications should use to PQcancelCreate(), where we have more options. I'm not quite sold on the change to PQcancelCreate(). The current behavior seems nicer: if cancellation is not available because the server didn't send a cancellation key, PQcancelCreate() returns a (cancel) connection object that's in a failed state with an error message explaining what's wrong. The client can choose to continue without cancellation capability, or bail out. Are there any known drivers that require the change to PQcancelCreate()? BTW, if the server doesn't send a BackendKeyData, PQbackendPID() returns 0. Not much we can do about that. - Heikki
Commits
-
Revert unnecessary check for NULL
- 5a26a3e4eeb2 18.0 landed
- 807ee417e562 19 (unreleased) landed
-
libpq: Be strict about cancel key lengths
- e7ff96853ea7 18.0 landed
- e411a8d25a4b 19 (unreleased) landed
-
libpq: Handle OOM by disconnecting instead of hanging or skipping msgs
- 8aa287c9061b 18.0 landed
- f6f0542266f0 19 (unreleased) landed
-
libpq: Complain about missing BackendKeyData later with PGgetCancel()
- 42b1480eb2c6 18.0 landed
- a4801eb691ed 19 (unreleased) landed