TCP_backend_v4.patch
application/octet-stream
Filename: TCP_backend_v4.patch
Type: application/octet-stream
Part: 0
Message:
RE: Timeout parameters
Patch
Format: unified
Series: patch v4
| File | + | − |
|---|---|---|
| doc/src/sgml/config.sgml | 43 | 0 |
| src/backend/libpq/pqcomm.c | 18 | 0 |
| src/backend/utils/misc/guc.c | 31 | 0 |
| src/include/libpq/libpq-be.h | 1 | 0 |
| src/include/utils/guc.h | 1 | 0 |
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index b6f5822b84..7f7ba2cfe2 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -924,6 +924,49 @@ include_dir 'conf.d'
</listitem>
</varlistentry>
+ <varlistentry id="guc-tcp-user-timeout" xreflabel="tcp_user_timeout">
+ <term><varname>tcp_user_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>tcp_user_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Define a wrapper for TCP_USER_TIMEOUT socket option of libpq connection.
+ </para>
+ <para>
+ Specifies the number of milliseconds after which a TCP connection can be
+ aborted by the operation system due to network problems when the data is
+ transmitting through this connection (sending/receiving). A value of 0 uses
+ the system default. This parameter is supported only on systems that support
+ TCP_USER_TIMEOUT or an equivalent socket option, and on Windows; on other
+ systems, it must be zero. In sessions connected via a Unix-domain socket,
+ this parameter is ignored and always reads as zero.
+ </para>
+ <note>
+ <para>
+ This parameter is not supported on Windows, and must be zero.
+ </para>
+ <para>
+ To enable full control under TCP connection use this option together with
+ keepalive.
+ </para>
+ </note>
+ </listitem>
+ <listitem>
+ <para>
+ Specify in milliseconds the time to disconnect to the client
+ when there is no ack packet from the client to the server's data transmission.
+ This parameter is supported on linux version 2.6.37 or later.
+ </para>
+ <note>
+ <para>
+ This parameter is not supported on Windows.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</sect2>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index c39617a430..b649237051 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -825,6 +825,7 @@ StreamConnection(pgsocket server_fd, Port *port)
(void) pq_setkeepalivesidle(tcp_keepalives_idle, port);
(void) pq_setkeepalivesinterval(tcp_keepalives_interval, port);
(void) pq_setkeepalivescount(tcp_keepalives_count, port);
+ (void) pq_settcpusertimeout(tcp_user_timeout, port);
}
return STATUS_OK;
@@ -1926,3 +1927,20 @@ pq_setkeepalivescount(int count, Port *port)
return STATUS_OK;
}
+
+int
+pq_settcpusertimeout(int timeout, Port *port)
+{
+#ifdef TCP_USER_TIMEOUT
+ if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
+ return STATUS_OK;
+
+ if (setsockopt(port->sock, IPPROTO_TCP, 18,
+ (char *) &timeout, sizeof(timeout)) << 0 && errno != ENOPROTOOPT)
+ {
+ elog(LOG, "setsockopt(TCP_USER_TIMEOUT) failed: %m");
+ return STATUS_ERROR;
+ }
+#endif
+ return STATUS_OK;
+}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index c216ed0922..b0c6049e17 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -180,9 +180,11 @@ static const char *show_archive_command(void);
static void assign_tcp_keepalives_idle(int newval, void *extra);
static void assign_tcp_keepalives_interval(int newval, void *extra);
static void assign_tcp_keepalives_count(int newval, void *extra);
+static void assign_tcp_user_timeout(int newval, void *extra);
static const char *show_tcp_keepalives_idle(void);
static const char *show_tcp_keepalives_interval(void);
static const char *show_tcp_keepalives_count(void);
+static const char *show_tcp_user_timeout(void);
static bool check_maxconnections(int *newval, void **extra, GucSource source);
static bool check_max_worker_processes(int *newval, void **extra, GucSource source);
static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source);
@@ -513,6 +515,7 @@ char *application_name;
int tcp_keepalives_idle;
int tcp_keepalives_interval;
int tcp_keepalives_count;
+int tcp_user_timeout;
/*
* SSL renegotiation was been removed in PostgreSQL 9.5, but we tolerate it
@@ -3142,6 +3145,17 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
+ {
+ {"tcp_user_timeout", PGC_USERSET, CLIENT_CONN_OTHER,
+ gettext_noop("TCP user timeout."),
+ gettext_noop("A value of 0 uses the system default."),
+ GUC_UNIT_MS | GUC_NOT_IN_SAMPLE
+ },
+ &tcp_user_timeout,
+ 12000, 0, INT_MAX,
+ NULL, assign_tcp_user_timeout, show_tcp_user_timeout
+ },
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL
@@ -10883,6 +10897,23 @@ show_tcp_keepalives_count(void)
return nbuf;
}
+static void
+assign_tcp_user_timeout(int newval, void *extra)
+{
+ /* See comments in assign_tcp_keepalives_idle */
+ (void) pq_settcpusertimeout(newval, MyProcPort);
+}
+
+static const char*
+show_tcp_user_timeout(void)
+{
+ /* See comments in assign_tcp_keepalives_idle */
+ static char nbuf[16];
+
+ snprintf(nbuf, sizeof(nbuf), "%d", tcp_user_timeout);
+ return nbuf;
+}
+
static bool
check_maxconnections(int *newval, void **extra, GucSource source)
{
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 7570649b5b..ffce7d5a8e 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -288,5 +288,6 @@ extern int pq_getkeepalivescount(Port *port);
extern int pq_setkeepalivesidle(int idle, Port *port);
extern int pq_setkeepalivesinterval(int interval, Port *port);
extern int pq_setkeepalivescount(int count, Port *port);
+extern int pq_settcpusertimeout(int timeout, Port *port);
#endif /* LIBPQ_BE_H */
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index c07e7b945e..0d023965b2 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -268,6 +268,7 @@ extern PGDLLIMPORT char *application_name;
extern int tcp_keepalives_idle;
extern int tcp_keepalives_interval;
extern int tcp_keepalives_count;
+extern int tcp_user_timeout;
#ifdef TRACE_SORT
extern bool trace_sort;