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

Commitd8cd283

Browse files
committed
Add TCP keepalive support to libpq.
This adds four additional connection parameters to libpq: keepalives,keepalives_idle, keepalives_count, and keepalives_interval.keepalives default to on, per discussion, but can be turned off byspecifying keepalives=0. The remaining parameters, where supported,can be used to adjust how often keepalives are sent and how manycan be lost before the connection is broken.The immediate motivation for this patch is to make sure thatwalreceiver will eventually notice if the master reboots withoutclosing the connection cleanly, but it should be helpful in othercases as well.Tollef Fog Heen, Fujii Masao, and me.
1 parentc1b6179 commitd8cd283

File tree

3 files changed

+238
-3
lines changed

3 files changed

+238
-3
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.308 2010/06/17 16:03:30 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.309 2010/06/23 21:54:13 rhaas Exp $ -->
22

33
<chapter id="libpq">
44
<title><application>libpq</application> - C Library</title>
@@ -280,6 +280,57 @@
280280
</listitem>
281281
</varlistentry>
282282

283+
<varlistentry id="libpq-keepalives" xreflabel="keepalives">
284+
<term><literal>keepalives</literal></term>
285+
<listitem>
286+
<para>
287+
Controls whether TCP keepalives are used. The default value is 1,
288+
meaning on, but you can change this to 0, meaning off, if keepalives
289+
are not wanted. This parameter is ignored for connections made via
290+
a Unix-domain socket.
291+
</para>
292+
</listitem>
293+
</varlistentry>
294+
295+
<varlistentry id="libpq-keepalives-idle" xreflabel="keepalives_idle">
296+
<term><literal>keepalives_idle</literal></term>
297+
<listitem>
298+
<para>
299+
On systems that support the <symbol>TCP_KEEPIDLE</symbol> socket
300+
option, specifies the number of seconds between sending keepalives
301+
on an otherwise idle connection. A value of zero uses the system
302+
default. This parameter is ignored for connections made via a
303+
Unix-domain socket, or if keepalives are disabled.
304+
</para>
305+
</listitem>
306+
</varlistentry>
307+
308+
<varlistentry id="libpq-keepalives-interval" xreflabel="keepalives_interval">
309+
<term><literal>keepalives_interval</literal></term>
310+
<listitem>
311+
<para>
312+
On systems that support the <symbol>TCP_KEEPINTVL</symbol> socket
313+
option, specifies how long, in seconds, to wait for a response to a
314+
keepalive before retransmitting. A value of zero uses the system
315+
default. This parameter is ignored for connections made via a
316+
Unix-domain socket, or if keepalives are disabled.
317+
</para>
318+
</listitem>
319+
</varlistentry>
320+
321+
<varlistentry id="libpq-keepalives-count" xreflabel="keepalives_count">
322+
<term><literal>keepalives_count</literal></term>
323+
<listitem>
324+
<para>
325+
On systems that support the <symbol>TCP_KEEPCNT</symbol> socket
326+
option, specifies how many keepalives can be lost before the
327+
connection is considered dead. A value of zero uses the system
328+
default. This parameter is ignored for connections made via a
329+
Unix-domain socket, or if keepalives are disabled.
330+
</para>
331+
</listitem>
332+
</varlistentry>
333+
283334
<varlistentry id="libpq-connect-tty" xreflabel="tty">
284335
<term><literal>tty</literal></term>
285336
<listitem>

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

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.393 2010/05/26 21:39:27 tgl Exp $
11+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.394 2010/06/23 21:54:13 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -183,6 +183,18 @@ static const PQconninfoOption PQconninfoOptions[] = {
183183
{"fallback_application_name",NULL,NULL,NULL,
184184
"Fallback-Application-Name","",64},
185185

186+
{"keepalives",NULL,NULL,NULL,
187+
"TCP-Keepalives","",1},/* should be just '0' or '1' */
188+
189+
{"keepalives_idle",NULL,NULL,NULL,
190+
"TCP-Keepalives-Idle","",10},/* strlen(INT32_MAX) == 10 */
191+
192+
{"keepalives_interval",NULL,NULL,NULL,
193+
"TCP-Keepalives-Interval","",10},/* strlen(INT32_MAX) == 10 */
194+
195+
{"keepalives_count",NULL,NULL,NULL,
196+
"TCP-Keepalives-Count","",10},/* strlen(INT32_MAX) == 10 */
197+
186198
#ifdefUSE_SSL
187199

188200
/*
@@ -552,6 +564,14 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
552564
conn->pgpass=tmp ?strdup(tmp) :NULL;
553565
tmp=conninfo_getval(connOptions,"connect_timeout");
554566
conn->connect_timeout=tmp ?strdup(tmp) :NULL;
567+
tmp=conninfo_getval(connOptions,"keepalives");
568+
conn->keepalives=tmp ?strdup(tmp) :NULL;
569+
tmp=conninfo_getval(connOptions,"keepalives_idle");
570+
conn->keepalives_idle=tmp ?strdup(tmp) :NULL;
571+
tmp=conninfo_getval(connOptions,"keepalives_interval");
572+
conn->keepalives_interval=tmp ?strdup(tmp) :NULL;
573+
tmp=conninfo_getval(connOptions,"keepalives_count");
574+
conn->keepalives_count=tmp ?strdup(tmp) :NULL;
555575
tmp=conninfo_getval(connOptions,"sslmode");
556576
conn->sslmode=tmp ?strdup(tmp) :NULL;
557577
tmp=conninfo_getval(connOptions,"sslkey");
@@ -943,6 +963,119 @@ connectFailureMessage(PGconn *conn, int errorno)
943963
}
944964
}
945965

966+
/*
967+
* Should we use keepalives? Returns 1 if yes, 0 if no, and -1 if
968+
* conn->keepalives is set to a value which is not parseable as an
969+
* integer.
970+
*/
971+
staticint
972+
useKeepalives(PGconn*conn)
973+
{
974+
char*ep;
975+
intval;
976+
977+
if (conn->keepalives==NULL)
978+
return1;
979+
val=strtol(conn->keepalives,&ep,10);
980+
if (*ep)
981+
return-1;
982+
returnval!=0 ?1 :0;
983+
}
984+
985+
/*
986+
* Set the keepalive idle timer.
987+
*/
988+
staticint
989+
setKeepalivesIdle(PGconn*conn)
990+
{
991+
intidle;
992+
993+
if (conn->keepalives_idle==NULL)
994+
return1;
995+
996+
idle=atoi(conn->keepalives_idle);
997+
if (idle<0)
998+
idle=0;
999+
1000+
#ifdefTCP_KEEPIDLE
1001+
if (setsockopt(conn->sock,IPPROTO_TCP,TCP_KEEPIDLE,
1002+
(char*)&idle,sizeof(idle))<0)
1003+
{
1004+
charsebuf[256];
1005+
1006+
appendPQExpBuffer(&conn->errorMessage,
1007+
libpq_gettext("setsockopt(TCP_KEEPIDLE) failed: %s\n"),
1008+
SOCK_STRERROR(SOCK_ERRNO,sebuf,sizeof(sebuf)));
1009+
return0;
1010+
}
1011+
#endif
1012+
1013+
return1;
1014+
}
1015+
1016+
/*
1017+
* Set the keepalive interval.
1018+
*/
1019+
staticint
1020+
setKeepalivesInterval(PGconn*conn)
1021+
{
1022+
intinterval;
1023+
1024+
if (conn->keepalives_interval==NULL)
1025+
return1;
1026+
1027+
interval=atoi(conn->keepalives_interval);
1028+
if (interval<0)
1029+
interval=0;
1030+
1031+
#ifdefTCP_KEEPINTVL
1032+
if (setsockopt(conn->sock,IPPROTO_TCP,TCP_KEEPINTVL,
1033+
(char*)&interval,sizeof(interval))<0)
1034+
{
1035+
charsebuf[256];
1036+
1037+
appendPQExpBuffer(&conn->errorMessage,
1038+
libpq_gettext("setsockopt(TCP_KEEPINTVL) failed: %s\n"),
1039+
SOCK_STRERROR(SOCK_ERRNO,sebuf,sizeof(sebuf)));
1040+
return0;
1041+
}
1042+
#endif
1043+
1044+
return1;
1045+
}
1046+
1047+
/*
1048+
* Set the count of lost keepalive packets that will trigger a connection
1049+
* break.
1050+
*/
1051+
staticint
1052+
setKeepalivesCount(PGconn*conn)
1053+
{
1054+
intcount;
1055+
1056+
if (conn->keepalives_count==NULL)
1057+
return1;
1058+
1059+
count=atoi(conn->keepalives_count);
1060+
if (count<0)
1061+
count=0;
1062+
1063+
#ifdefTCP_KEEPCNT
1064+
if (setsockopt(conn->sock,IPPROTO_TCP,TCP_KEEPCNT,
1065+
(char*)&count,sizeof(count))<0)
1066+
{
1067+
charsebuf[256];
1068+
1069+
appendPQExpBuffer(&conn->errorMessage,
1070+
libpq_gettext("setsockopt(TCP_KEEPCNT) failed: %s\n"),
1071+
SOCK_STRERROR(SOCK_ERRNO,sebuf,sizeof(sebuf)));
1072+
return0;
1073+
}
1074+
#endif
1075+
1076+
return1;
1077+
}
1078+
9461079

9471080
/* ----------
9481081
* connectDBStart -
@@ -1329,6 +1462,45 @@ PQconnectPoll(PGconn *conn)
13291462
}
13301463
#endif/* F_SETFD */
13311464

1465+
if (!IS_AF_UNIX(addr_cur->ai_family))
1466+
{
1467+
inton=1;
1468+
intusekeepalives=useKeepalives(conn);
1469+
interr=0;
1470+
1471+
if (usekeepalives<0)
1472+
{
1473+
appendPQExpBuffer(&conn->errorMessage,
1474+
libpq_gettext("keepalives parameter must be an integer\n"));
1475+
err=1;
1476+
}
1477+
elseif (usekeepalives==0)
1478+
{
1479+
/* Do nothing */
1480+
}
1481+
elseif (setsockopt(conn->sock,
1482+
SOL_SOCKET,SO_KEEPALIVE,
1483+
(char*)&on,sizeof(on))<0)
1484+
{
1485+
appendPQExpBuffer(&conn->errorMessage,
1486+
libpq_gettext("setsockopt(SO_KEEPALIVE) failed: %s\n"),
1487+
SOCK_STRERROR(SOCK_ERRNO,sebuf,sizeof(sebuf)));
1488+
err=1;
1489+
}
1490+
elseif (!setKeepalivesIdle(conn)
1491+
|| !setKeepalivesInterval(conn)
1492+
|| !setKeepalivesCount(conn))
1493+
err=1;
1494+
1495+
if (err)
1496+
{
1497+
closesocket(conn->sock);
1498+
conn->sock=-1;
1499+
conn->addr_cur=addr_cur->ai_next;
1500+
continue;
1501+
}
1502+
}
1503+
13321504
/*----------
13331505
* We have three methods of blocking SIGPIPE during
13341506
* send() calls to this socket:
@@ -2290,6 +2462,14 @@ freePGconn(PGconn *conn)
22902462
free(conn->pguser);
22912463
if (conn->pgpass)
22922464
free(conn->pgpass);
2465+
if (conn->keepalives)
2466+
free(conn->keepalives);
2467+
if (conn->keepalives_idle)
2468+
free(conn->keepalives_idle);
2469+
if (conn->keepalives_interval)
2470+
free(conn->keepalives_interval);
2471+
if (conn->keepalives_count)
2472+
free(conn->keepalives_count);
22932473
if (conn->sslmode)
22942474
free(conn->sslmode);
22952475
if (conn->sslcert)

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
15-
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.150 2010/03/13 14:55:57 momjian Exp $
15+
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.151 2010/06/23 21:54:13 rhaas Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -300,6 +300,10 @@ struct pg_conn
300300
char*replication;/* connect as the replication standby? */
301301
char*pguser;/* Postgres username and password, if any */
302302
char*pgpass;
303+
char*keepalives;/* use TCP keepalives? */
304+
char*keepalives_idle;/* time between TCP keepalives */
305+
char*keepalives_interval;/* time between TCP keepalive retransmits */
306+
char*keepalives_count;/* maximum number of TCP keepalive retransmits */
303307
char*sslmode;/* SSL mode (require,prefer,allow,disable) */
304308
char*sslkey;/* client key filename */
305309
char*sslcert;/* client certificate filename */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp