mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 17:02:08 +03:00
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 <s.cherkashin@postgrespro.ru> Author: Thomas Munro <thomas.munro@gmail.com> Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Reviewed-by: Tatsuo Ishii <ishii@sraoss.co.jp> Reviewed-by: Konstantin Knizhnik <k.knizhnik@postgrespro.ru> Reviewed-by: Zhihong Yu <zyu@yugabyte.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Maksim Milyutin <milyutinma@gmail.com> Reviewed-by: Tsunakawa, Takayuki/綱川 貴之 <tsunakawa.takay@fujitsu.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> (much earlier version) Discussion: https://postgr.es/m/77def86b27e41f0efcba411460e929ae%40postgrespro.ru
This commit is contained in:
@ -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 */
|
||||
|
Reference in New Issue
Block a user