| From: | "Jelte Fennema-Nio" <me(at)jeltef(dot)nl> |
|---|---|
| To: | "PostgreSQL Hackers" <pgsql-hackers(at)lists(dot)postgresql(dot)org>, "Tatsuo Ishii" <ishii(at)postgresql(dot)org> |
| Cc: | "Jacob Champion" <jacob(dot)champion(at)enterprisedb(dot)com>, "Tomas Vondra" <tomas(at)vondra(dot)me>, "Zsolt Parragi" <zsolt(dot)parragi(at)percona(dot)com>, "Dave Cramer" <davecramer(at)gmail(dot)com>, "Kirill Reshke" <reshkekirill(at)gmail(dot)com>, <jnasby(at)upgrade(dot)com> |
| Subject: | Add read-only disconnect_requested GUC for graceful client disconnect |
| Date: | 2026-07-11 08:15:48 |
| Message-ID: | DJVLCL7PV7U6.35IJF87CZZ61Y@jeltef.nl |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
This is a redesign of the previous GoAway proposal[4] but this time
*without making any protocol changes*:
This commit introduces a new read-only disconnect_requested GUC (similar
to in_hot_standby) that the server can turn on to politely request the
client to disconnect/reconnect when convenient. Because the GUC is
flagged GUC_REPORT, its new value is reported to the client in a
ParameterStatus message whenever it changes. This request is advisory
only: the connection remains fully functional and clients may continue
executing queries and starting new transactions. "When convenient" is
obviously not very well defined, but the primary targets are clients
that maintain a connection pool. Such clients should
disconnect/reconnect a connection in the pool when there's no user of
that connection. This is similar to how such clients often currently
remove a connection from the pool after the connection hits a maximum
lifetime of e.g. 1 hour[1][2]. Since psql does not have such a
connection pool all it does is tell the user when the GUC changes, so
that the user might choose a "convenient" time themselves.
The GUC defaults to "off" and is set to "on" by the server in two
situations:
1. Using a new pg_request_disconnect_backend(pid) function the GUC can be
set to "on" for a specific backend using a procsignal.
2. During "smart" shutdown the GUC is set to "on" for all backends.
The pg_request_disconnect_backend() function is effectively a graceful
counterpart to pg_terminate_backend(). This function can be useful to
trigger a graceful reconnect of a specific backend. This can for
instance be used if the backend is using a lot of memory, and an
operator wants the client to reconnect to clear its catalog caches
but without causing any queries to fail.
The "smart" shutdown mode (aka sending SIGTERM to postmaster) is in
practice usually the *least smart* shutdown mode that a user can use. A
single client can indefinitely keep the server from actually shutting
down, while any new connection attempts will be greeted with a FATAL
error. That's not the behavior you want for your primary in production.
The only usage for smart shutdown that currently makes sense is for a
graceful shutdown or switchover of a read replica. Setting
disconnect_requested to "on" during smart shutdown allows for
cooperating clients to disconnect earlier and thus for the
shutdown/switchover to complete quicker.
It can now even make sense to use "smart" shutdown for a primary too, as
long as it's done in combination with "fast" shutdown: If you first
trigger a "smart" shutdown and then trigger a "fast" shutdown after
5 seconds, then all the cooperating clients will have disconnected
gracefully before the fast shutdown would have killed them
mid-transaction. Gracefully recovering from a shutdown mid-transaction
is often non-trivial for an application. Clients might be receiving errors
for later reconnection attempts, but those are often much easier to
handle gracefully (a simple retry is all that's needed).
Finally, this new setting is also intended to be advertised by other
servers implementing the Postgres protocol. For instance proxies like
PgBouncer can send a ParameterStatus message that sets
disconnect_requested to "on" when they want their clients to disconnect
so they can do a rolling restart or switchover without any downtime.
Specifically PgBouncer would be sending this when an operator shuts it
down using SHUTDOWN WAIT_FOR_CLIENTS[3].
Two notes of suboptimal behavior:
1. Proxies using this to report their own shutdown will cause the value
of the ParameterStatus to be different than the value that
"SHOW disconnect_requested" reports, unless they also intercept those
queries.
2. Right now the ParameterStatus is only sent at completion of a query,
not while a connection is idle. It'd be better if a connection pool
could check the current state of idle connections too, before handing
them off again. I'll address this in a follow-up commit once it's
agreed on that the general approach is sensible.
[1]: https://www.pgbouncer.org/config.html#server_lifetime
[2]: https://github.com/brettwooldridge/HikariCP (see maxLifetime setting)
[3]: https://www.pgbouncer.org/usage.html#shutdown
[4]: https://www.postgresql.org/message-id/DDPQ1RV5FE9U.I2WW34NGRD8Z@jeltef.nl
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Add-read-only-disconnect_requested-GUC-for-gracef.patch | text/x-patch | 36.1 KB |
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | jian he | 2026-07-11 07:45:54 | Re: Row pattern recognition |