| From: | "Jelte Fennema-Nio" <postgres(at)jeltef(dot)nl> |
|---|---|
| To: | "Heikki Linnakangas" <hlinnaka(at)iki(dot)fi>, "PostgreSQL Hackers" <pgsql-hackers(at)lists(dot)postgresql(dot)org>, "Alvaro Herrera" <alvherre(at)alvh(dot)no-ip(dot)org>, "Jacob Champion" <jacob(dot)champion(at)enterprisedb(dot)com> |
| Subject: | Re: Don't use the deprecated and insecure PQcancel in our frontend tools anymore |
| Date: | 2026-03-15 15:09:24 |
| Message-ID: | DH3G8Z262WNH.DMDDI1DM95OG@jeltef.nl |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Fri Mar 6, 2026 at 8:51 PM CET, Heikki Linnakangas wrote:
> I worry how this behaves if establishing the cancel connection gets
> stuck for a long time. Because of a network hiccup, for example. That's
> also not a new problem though; it's perhaps even worse today, if the
> signal handler gets stuck for a long time, trying to establish the
> connection. Still, would be good to do some testing with a bad network.
After thinking on this again, I thought of a much easier solution to
this problem than the direction I was exploring in my previous response
to this:
We can have SetCancelConn() and ResetCancelConn() wait for any pending
cancel to complete before letting them replace/remove the cancelConn.
That way even in case of a bad network, we know that an already
in-flight cancel request will never cancel a query from a next
SetCancelConn() call. It does mean that you cannot submit a new query
before we've received a response to the in-flight cancel request (either
because the hiccup is reselved or because TCP timeouts report a
failure). That's the current behaviour too with running PQcancel in the
signal handler, and I also think that's the behaviour that makes the
most sense.
Attached is a patchset that does this.
To ensure that it worked correctly, I mimicked network issues by running
the following iptables command after already having connected with psql:
sudo iptables -A INPUT -p tcp --dport 5432 -m state --state NEW -j DROP
That command drops all new incoming connections to the server, but
allows already established connections to continue working. Which means
that any new cancel connections will not be able to connect.
You can allow the traffic again with:
sudo iptables -D INPUT -p tcp --dport 5432 -m state --state NEW -j DROP
To see what happens when the connection attempt never goes through I
used:
sudo sysctl net.ipv4.tcp_syn_retries=2
sudo sysctl net.ipv4.tcp_retries2=3
This is what happens then:
localhost jelte(at)postgres:5432-1484255=# select pg_sleep(5);
^CSending cancel request
Time: 5005.833 ms (00:05.006)
Could not send cancel request: connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection timed out
Is the server running on that host and accepting TCP/IP connections?
localhost jelte(at)postgres:5432-1484255=#
The query succeeds after 5 seconds, but the prompt does not become
interactive until a little while after that when the cancel request
error is also shown.
| Attachment | Content-Type | Size |
|---|---|---|
| v6-0001-Move-Windows-pthread-compatibility-functions-to-s.patch | text/x-patch | 2.9 KB |
| v6-0002-Don-t-use-deprecated-and-insecure-PQcancel-psql-a.patch | text/x-patch | 15.3 KB |
| v6-0003-pg_dump-Don-t-use-the-deprecated-and-insecure-PQc.patch | text/x-patch | 23.0 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Pavel Stehule | 2026-03-15 15:20:42 | Re: WIP - xmlvalidate implementation from TODO list |
| Previous Message | Mahendra Singh Thalor | 2026-03-15 14:06:14 | Re: bug: pg_dumpall with --data-only and --clean options is giving an error after some dump |