diff options
author | Thomas Munro | 2021-04-02 19:52:30 +0000 |
---|---|---|
committer | Thomas Munro | 2021-04-02 20:02:41 +0000 |
commit | c30f54ad732ca5c8762bb68bbe0f51de9137dd72 (patch) | |
tree | 5086aba82cce9832ed537b726af643d8edf9b89c /src/backend/tcop/postgres.c | |
parent | 174edbe9f9c1538ab3347474e96d176223591cd1 (diff) |
Detect POLLHUP/POLLRDHUP while running queries.
Provide a new GUC check_client_connection_interval that can be used to
check whether the client connection has gone away, while running very
long queries. It is disabled by default.
For now this uses a non-standard Linux extension (also adopted by at
least one other OS). POLLRDHUP is not defined by POSIX, and other OSes
don't have a reliable way to know if a connection was closed without
actually trying to read or write.
In future we might consider trying to send a no-op/heartbeat message
instead, but that could require protocol changes.
Author: Sergey Cherkashin <[email protected]>
Author: Thomas Munro <[email protected]>
Reviewed-by: Thomas Munro <[email protected]>
Reviewed-by: Tatsuo Ishii <[email protected]>
Reviewed-by: Konstantin Knizhnik <[email protected]>
Reviewed-by: Zhihong Yu <[email protected]>
Reviewed-by: Andres Freund <[email protected]>
Reviewed-by: Maksim Milyutin <[email protected]>
Reviewed-by: Tsunakawa, Takayuki/綱川 貴之 <[email protected]>
Reviewed-by: Tom Lane <[email protected]> (much earlier version)
Discussion: https://postgr.es/m/77def86b27e41f0efcba411460e929ae%40postgrespro.ru
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 2b1b68109fd..ad351e2fd1e 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -102,6 +102,9 @@ int max_stack_depth = 100; /* wait N seconds to allow attach from a debugger */ int PostAuthDelay = 0; +/* Time between checks that the client is still connected. */ +int client_connection_check_interval = 0; + /* ---------------- * private typedefs etc * ---------------- @@ -2671,6 +2674,14 @@ start_xact_command(void) * not desired, the timeout has to be disabled explicitly. */ enable_statement_timeout(); + + /* Start timeout for checking if the client has gone away if necessary. */ + if (client_connection_check_interval > 0 && + IsUnderPostmaster && + MyProcPort && + !get_timeout_active(CLIENT_CONNECTION_CHECK_TIMEOUT)) + enable_timeout_after(CLIENT_CONNECTION_CHECK_TIMEOUT, + client_connection_check_interval); } static void @@ -3149,6 +3160,27 @@ ProcessInterrupts(void) (errcode(ERRCODE_ADMIN_SHUTDOWN), errmsg("terminating connection due to administrator command"))); } + + if (CheckClientConnectionPending) + { + CheckClientConnectionPending = false; + + /* + * Check for lost connection and re-arm, if still configured, but not + * if we've arrived back at DoingCommandRead state. We don't want to + * wake up idle sessions, and they already know how to detect lost + * connections. + */ + if (!DoingCommandRead && client_connection_check_interval > 0) + { + if (!pq_check_connection()) + ClientConnectionLost = true; + else + enable_timeout_after(CLIENT_CONNECTION_CHECK_TIMEOUT, + client_connection_check_interval); + } + } + if (ClientConnectionLost) { QueryCancelPending = false; /* lost connection trumps QueryCancel */ |