diff options
author | Thomas Munro <tmunro@postgresql.org> | 2021-04-03 08:52:30 +1300 |
---|---|---|
committer | Thomas Munro <tmunro@postgresql.org> | 2021-04-03 09:02:41 +1300 |
commit | c30f54ad732ca5c8762bb68bbe0f51de9137dd72 (patch) | |
tree | 5086aba82cce9832ed537b726af643d8edf9b89c /src/backend/libpq/pqcomm.c | |
parent | 174edbe9f9c1538ab3347474e96d176223591cd1 (diff) | |
download | postgresql-c30f54ad732ca5c8762bb68bbe0f51de9137dd72.tar.gz postgresql-c30f54ad732ca5c8762bb68bbe0f51de9137dd72.zip |
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
Diffstat (limited to 'src/backend/libpq/pqcomm.c')
-rw-r--r-- | src/backend/libpq/pqcomm.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 4c7b1e7bfdf..4cd6d6dfbb9 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -54,6 +54,9 @@ */ #include "postgres.h" +#ifdef HAVE_POLL_H +#include <poll.h> +#endif #include <signal.h> #include <fcntl.h> #include <grp.h> @@ -1921,3 +1924,40 @@ pq_settcpusertimeout(int timeout, Port *port) return STATUS_OK; } + +/* + * Check if the client is still connected. + */ +bool +pq_check_connection(void) +{ +#if defined(POLLRDHUP) + /* + * POLLRDHUP is a Linux extension to poll(2) to detect sockets closed by + * the other end. We don't have a portable way to do that without + * actually trying to read or write data on other systems. We don't want + * to read because that would be confused by pipelined queries and COPY + * data. Perhaps in future we'll try to write a heartbeat message instead. + */ + struct pollfd pollfd; + int rc; + + pollfd.fd = MyProcPort->sock; + pollfd.events = POLLOUT | POLLIN | POLLRDHUP; + pollfd.revents = 0; + + rc = poll(&pollfd, 1, 0); + + if (rc < 0) + { + ereport(COMMERROR, + (errcode_for_socket_access(), + errmsg("could not poll socket: %m"))); + return false; + } + else if (rc == 1 && (pollfd.revents & (POLLHUP | POLLRDHUP))) + return false; +#endif + + return true; +} |