Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit249d649

Browse files
committed
Add support TCP user timeout in libpq and the backend server
Similarly to the set of parameters for keepalive, a connection parameterfor libpq is added as well as a backend GUC, called tcp_user_timeout.Increasing the TCP user timeout is useful to allow a connection tosurvive extended periods without end-to-end connection, and decreasingit allows application to fail faster. By default, the parameter is 0,which makes the connection use the system default, and follows a logicclose to the keepalive parameters in its handling. When connectingthrough a Unix-socket domain, the parameters have no effect.Author: Ryohei NagauraReviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, KirkJamison, Mikalai Keida, Takayuki Tsunakawa, Andrei YahorauDiscussion:https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
1 parent959d00e commit249d649

File tree

11 files changed

+198
-2
lines changed

11 files changed

+198
-2
lines changed

‎contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ ALTER SERVER testserver1 OPTIONS (
151151
keepalives 'value',
152152
keepalives_idle 'value',
153153
keepalives_interval 'value',
154+
tcp_user_timeout 'value',
154155
-- requiressl 'value',
155156
sslcompression 'value',
156157
sslmode 'value',

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ ALTER SERVER testserver1 OPTIONS (
164164
keepalives'value',
165165
keepalives_idle'value',
166166
keepalives_interval'value',
167+
tcp_user_timeout'value',
167168
-- requiressl 'value',
168169
sslcompression'value',
169170
sslmode'value',

‎doc/src/sgml/config.sgml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,31 @@ include_dir 'conf.d'
939939
</listitem>
940940
</varlistentry>
941941

942+
<varlistentry id="guc-tcp-user-timeout" xreflabel="tcp_user_timeout">
943+
<term><varname>tcp_user_timeout</varname> (<type>integer</type>)
944+
<indexterm>
945+
<primary><varname>tcp_user_timeout</varname> configuration parameter</primary>
946+
</indexterm>
947+
</term>
948+
<listitem>
949+
<para>
950+
Specifies the number of milliseconds that transmitted data may
951+
remain unacknowledged before a connection is forcibly closed.
952+
A value of 0 uses the system default.
953+
This parameter is supported only on systems that support
954+
<symbol>TCP_USER_TIMEOUT</symbol>; on other systems, it must be zero.
955+
In sessions connected via a Unix-domain socket, this parameter is
956+
ignored and always reads as zero.
957+
</para>
958+
<note>
959+
<para>
960+
This parameter is not supported on Windows and on Linux version
961+
2.6.36 or older.
962+
</para>
963+
</note>
964+
</listitem>
965+
</varlistentry>
966+
942967
</variablelist>
943968
</sect2>
944969

‎doc/src/sgml/libpq.sgml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,20 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
12491249
</listitem>
12501250
</varlistentry>
12511251

1252+
<varlistentry id="libpq-tcp-user-timeout" xreflabel="libpq_tcp_user_timeout">
1253+
<term><literal>tcp_user_timeout</literal></term>
1254+
<listitem>
1255+
<para>
1256+
Controls the number of milliseconds that transmitted data may
1257+
remain unacknowledged before a connection is forcibly closed.
1258+
A value of zero uses the system default. This parameter is
1259+
ignored for connections made via a Unix-domain socket.
1260+
It is only supported on systems where <symbol>TCP_USER_TIMEOUT</symbol>
1261+
is available; on other systems, it has no effect.
1262+
</para>
1263+
</listitem>
1264+
</varlistentry>
1265+
12521266
<varlistentry id="libpq-connect-tty" xreflabel="tty">
12531267
<term><literal>tty</literal></term>
12541268
<listitem>

‎src/backend/libpq/pqcomm.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ StreamConnection(pgsocket server_fd, Port *port)
825825
(void)pq_setkeepalivesidle(tcp_keepalives_idle,port);
826826
(void)pq_setkeepalivesinterval(tcp_keepalives_interval,port);
827827
(void)pq_setkeepalivescount(tcp_keepalives_count,port);
828+
(void)pq_settcpusertimeout(tcp_user_timeout,port);
828829
}
829830

830831
returnSTATUS_OK;
@@ -1926,3 +1927,75 @@ pq_setkeepalivescount(int count, Port *port)
19261927

19271928
returnSTATUS_OK;
19281929
}
1930+
1931+
int
1932+
pq_gettcpusertimeout(Port*port)
1933+
{
1934+
#ifdefTCP_USER_TIMEOUT
1935+
if (port==NULL||IS_AF_UNIX(port->laddr.addr.ss_family))
1936+
return0;
1937+
1938+
if (port->tcp_user_timeout!=0)
1939+
returnport->tcp_user_timeout;
1940+
1941+
if (port->default_tcp_user_timeout==0)
1942+
{
1943+
ACCEPT_TYPE_ARG3size=sizeof(port->default_tcp_user_timeout);
1944+
1945+
if (getsockopt(port->sock,IPPROTO_TCP,TCP_USER_TIMEOUT,
1946+
(char*)&port->default_tcp_user_timeout,
1947+
&size)<0)
1948+
{
1949+
elog(LOG,"getsockopt(%s) failed: %m","TCP_USER_TIMEOUT");
1950+
port->default_tcp_user_timeout=-1;/* don't know */
1951+
}
1952+
}
1953+
1954+
returnport->default_tcp_user_timeout;
1955+
#else
1956+
return0;
1957+
#endif
1958+
}
1959+
1960+
int
1961+
pq_settcpusertimeout(inttimeout,Port*port)
1962+
{
1963+
if (port==NULL||IS_AF_UNIX(port->laddr.addr.ss_family))
1964+
returnSTATUS_OK;
1965+
1966+
#ifdefTCP_USER_TIMEOUT
1967+
if (timeout==port->tcp_user_timeout)
1968+
returnSTATUS_OK;
1969+
1970+
if (port->default_tcp_user_timeout <=0)
1971+
{
1972+
if (pq_gettcpusertimeout(port)<0)
1973+
{
1974+
if (timeout==0)
1975+
returnSTATUS_OK;/* default is set but unknown */
1976+
else
1977+
returnSTATUS_ERROR;
1978+
}
1979+
}
1980+
1981+
if (timeout==0)
1982+
timeout=port->default_tcp_user_timeout;
1983+
1984+
if (setsockopt(port->sock,IPPROTO_TCP,TCP_USER_TIMEOUT,
1985+
(char*)&timeout,sizeof(timeout))<0)
1986+
{
1987+
elog(LOG,"setsockopt(%s) failed: %m","TCP_USER_TIMEOUT");
1988+
returnSTATUS_ERROR;
1989+
}
1990+
1991+
port->tcp_user_timeout=timeout;
1992+
#else
1993+
if (timeout!=0)
1994+
{
1995+
elog(LOG,"setsockopt(%s) not supported","TCP_USER_TIMEOUT");
1996+
returnSTATUS_ERROR;
1997+
}
1998+
#endif
1999+
2000+
returnSTATUS_OK;
2001+
}

‎src/backend/utils/misc/guc.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,11 @@ static const char *show_archive_command(void);
182182
staticvoidassign_tcp_keepalives_idle(intnewval,void*extra);
183183
staticvoidassign_tcp_keepalives_interval(intnewval,void*extra);
184184
staticvoidassign_tcp_keepalives_count(intnewval,void*extra);
185+
staticvoidassign_tcp_user_timeout(intnewval,void*extra);
185186
staticconstchar*show_tcp_keepalives_idle(void);
186187
staticconstchar*show_tcp_keepalives_interval(void);
187188
staticconstchar*show_tcp_keepalives_count(void);
189+
staticconstchar*show_tcp_user_timeout(void);
188190
staticboolcheck_maxconnections(int*newval,void**extra,GucSourcesource);
189191
staticboolcheck_max_worker_processes(int*newval,void**extra,GucSourcesource);
190192
staticboolcheck_autovacuum_max_workers(int*newval,void**extra,GucSourcesource);
@@ -530,6 +532,7 @@ char *application_name;
530532
inttcp_keepalives_idle;
531533
inttcp_keepalives_interval;
532534
inttcp_keepalives_count;
535+
inttcp_user_timeout;
533536

534537
/*
535538
* SSL renegotiation was been removed in PostgreSQL 9.5, but we tolerate it
@@ -3182,6 +3185,17 @@ static struct config_int ConfigureNamesInt[] =
31823185
NULL,NULL,NULL
31833186
},
31843187

3188+
{
3189+
{"tcp_user_timeout",PGC_USERSET,CLIENT_CONN_OTHER,
3190+
gettext_noop("TCP user timeout."),
3191+
gettext_noop("A value of 0 uses the system default."),
3192+
GUC_UNIT_MS
3193+
},
3194+
&tcp_user_timeout,
3195+
0,0,INT_MAX,
3196+
NULL,assign_tcp_user_timeout,show_tcp_user_timeout
3197+
},
3198+
31853199
/* End-of-list marker */
31863200
{
31873201
{NULL,0,0,NULL,NULL},NULL,0,0,0,NULL,NULL,NULL
@@ -11238,6 +11252,23 @@ show_tcp_keepalives_count(void)
1123811252
returnnbuf;
1123911253
}
1124011254

11255+
staticvoid
11256+
assign_tcp_user_timeout(intnewval,void*extra)
11257+
{
11258+
/* See comments in assign_tcp_keepalives_idle */
11259+
(void)pq_settcpusertimeout(newval,MyProcPort);
11260+
}
11261+
11262+
staticconstchar*
11263+
show_tcp_user_timeout(void)
11264+
{
11265+
/* See comments in assign_tcp_keepalives_idle */
11266+
staticcharnbuf[16];
11267+
11268+
snprintf(nbuf,sizeof(nbuf),"%d",pq_gettcpusertimeout(MyProcPort));
11269+
returnnbuf;
11270+
}
11271+
1124111272
staticbool
1124211273
check_maxconnections(int*newval,void**extra,GucSourcesource)
1124311274
{

‎src/backend/utils/misc/postgresql.conf.sample

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
#bonjour_name = ''# defaults to the computer name
7474
# (change requires restart)
7575

76-
# - TCPKeepalives -
76+
# - TCPsettings -
7777
# see "man 7 tcp" for details
7878

7979
#tcp_keepalives_idle = 0# TCP_KEEPIDLE, in seconds;
@@ -82,6 +82,8 @@
8282
# 0 selects the system default
8383
#tcp_keepalives_count = 0# TCP_KEEPCNT;
8484
# 0 selects the system default
85+
#tcp_user_timeout = 0# TCP_USER_TIMEOUT, in milliseconds;
86+
# 0 selects the system default
8587

8688
# - Authentication -
8789

‎src/include/libpq/libpq-be.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ typedef struct Port
155155
HbaLine*hba;
156156

157157
/*
158-
* TCP keepalive settings.
158+
* TCP keepaliveand user timeoutsettings.
159159
*
160160
* default values are 0 if AF_UNIX or not yet known; current values are 0
161161
* if AF_UNIX or using the default. Also, -1 in a default value means we
@@ -164,9 +164,11 @@ typedef struct Port
164164
intdefault_keepalives_idle;
165165
intdefault_keepalives_interval;
166166
intdefault_keepalives_count;
167+
intdefault_tcp_user_timeout;
167168
intkeepalives_idle;
168169
intkeepalives_interval;
169170
intkeepalives_count;
171+
inttcp_user_timeout;
170172

171173
/*
172174
* GSSAPI structures.
@@ -306,9 +308,11 @@ extern ProtocolVersion FrontendProtocol;
306308
externintpq_getkeepalivesidle(Port*port);
307309
externintpq_getkeepalivesinterval(Port*port);
308310
externintpq_getkeepalivescount(Port*port);
311+
externintpq_gettcpusertimeout(Port*port);
309312

310313
externintpq_setkeepalivesidle(intidle,Port*port);
311314
externintpq_setkeepalivesinterval(intinterval,Port*port);
312315
externintpq_setkeepalivescount(intcount,Port*port);
316+
externintpq_settcpusertimeout(inttimeout,Port*port);
313317

314318
#endif/* LIBPQ_BE_H */

‎src/include/utils/guc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ extern PGDLLIMPORT char *application_name;
271271
externinttcp_keepalives_idle;
272272
externinttcp_keepalives_interval;
273273
externinttcp_keepalives_count;
274+
externinttcp_user_timeout;
274275

275276
#ifdefTRACE_SORT
276277
externbooltrace_sort;

‎src/interfaces/libpq/fe-connect.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
270270
"TCP-Keepalives-Count","",10,/* strlen(INT32_MAX) == 10 */
271271
offsetof(structpg_conn,keepalives_count)},
272272

273+
{"tcp_user_timeout",NULL,NULL,NULL,
274+
"TCP-User-Timeout","",10,/* strlen(INT32_MAX) == 10 */
275+
offsetof(structpg_conn,pgtcp_user_timeout)},
276+
273277
/*
274278
* ssl options are allowed even without client SSL support because the
275279
* client can still handle SSL modes "disable" and "allow". Other
@@ -1833,6 +1837,41 @@ setKeepalivesWin32(PGconn *conn)
18331837
#endif/* SIO_KEEPALIVE_VALS */
18341838
#endif/* WIN32 */
18351839

1840+
/*
1841+
* Set the TCP user timeout.
1842+
*/
1843+
staticint
1844+
setTCPUserTimeout(PGconn*conn)
1845+
{
1846+
inttimeout;
1847+
1848+
if (conn->pgtcp_user_timeout==NULL)
1849+
return1;
1850+
1851+
if (!parse_int_param(conn->pgtcp_user_timeout,&timeout,conn,
1852+
"tcp_user_timeout"))
1853+
return0;
1854+
1855+
if (timeout<0)
1856+
timeout=0;
1857+
1858+
#ifdefTCP_USER_TIMEOUT
1859+
if (setsockopt(conn->sock,IPPROTO_TCP,TCP_USER_TIMEOUT,
1860+
(char*)&timeout,sizeof(timeout))<0)
1861+
{
1862+
charsebuf[256];
1863+
1864+
appendPQExpBuffer(&conn->errorMessage,
1865+
libpq_gettext("setsockopt(%s) failed: %s\n"),
1866+
"TCP_USER_TIMEOUT",
1867+
SOCK_STRERROR(SOCK_ERRNO,sebuf,sizeof(sebuf)));
1868+
return0;
1869+
}
1870+
#endif
1871+
1872+
return1;
1873+
}
1874+
18361875
/* ----------
18371876
* connectDBStart -
18381877
*Begin the process of making a connection to the backend.
@@ -2480,6 +2519,8 @@ PQconnectPoll(PGconn *conn)
24802519
err=1;
24812520
#endif/* SIO_KEEPALIVE_VALS */
24822521
#endif/* WIN32 */
2522+
elseif (!setTCPUserTimeout(conn))
2523+
err=1;
24832524

24842525
if (err)
24852526
{
@@ -3863,6 +3904,8 @@ freePGconn(PGconn *conn)
38633904
free(conn->pgtty);
38643905
if (conn->connect_timeout)
38653906
free(conn->connect_timeout);
3907+
if (conn->pgtcp_user_timeout)
3908+
free(conn->pgtcp_user_timeout);
38663909
if (conn->pgoptions)
38673910
free(conn->pgoptions);
38683911
if (conn->appname)

‎src/interfaces/libpq/libpq-int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ struct pg_conn
336336
char*pgtty;/* tty on which the backend messages is
337337
* displayed (OBSOLETE, NOT USED) */
338338
char*connect_timeout;/* connection timeout (numeric string) */
339+
char*pgtcp_user_timeout;/* tcp user timeout (numeric string) */
339340
char*client_encoding_initial;/* encoding to use */
340341
char*pgoptions;/* options to start the backend with */
341342
char*appname;/* application name */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp