Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1f54d43

Browse files
committed
Add GUC variables to control keep-alive times for idle, interval, and
count. Oliver Jowett
1 parent b2b6548 commit 1f54d43

File tree

7 files changed

+399
-7
lines changed

7 files changed

+399
-7
lines changed

doc/src/sgml/runtime.sgml

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.339 2005/07/23 21:05:45 tgl Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.340 2005/07/30 15:17:18 momjian Exp $
33
-->
44

55
<chapter Id="runtime">
@@ -894,6 +894,53 @@ SET ENABLE_SEQSCAN TO OFF;
894894
</listitem>
895895
</varlistentry>
896896

897+
<varlistentry id="guc-tcp-keepalives-idle" xreflabel="tcp_keepalives_idle">
898+
<term><varname>tcp_keepalives_idle</varname> (<type>integer</type>)</term>
899+
<indexterm>
900+
<primary><varname>tcp_keepalives_idle</> configuration parameter</primary>
901+
</indexterm>
902+
<listitem>
903+
<para>
904+
On systems that support the TCP_KEEPIDLE socket option, specifies the
905+
number of seconds between sending keepalives on an otherwise idle
906+
connection. A value of 0 uses the system default. If TCP_KEEPIDLE is
907+
not supported, this parameter must be 0. This option is ignored for
908+
connections made via a Unix-domain socket.
909+
</para>
910+
</listitem>
911+
</varlistentry>
912+
913+
<varlistentry id="guc-tcp-keepalives-interval" xreflabel="tcp_keepalives_interval">
914+
<term><varname>tcp_keepalives_interval</varname> (<type>integer</type>)</term>
915+
<indexterm>
916+
<primary><varname>tcp_keepalives_interval</> configuration parameter</primary>
917+
</indexterm>
918+
<listitem>
919+
<para>
920+
On systems that support the TCP_KEEPINTVL socket option, specifies how
921+
long, in seconds, to wait for a response to a keepalive before
922+
retransmitting. A value of 0 uses the system default. If TCP_KEEPINTVL
923+
is not supported, this parameter must be 0. This option is ignored
924+
for connections made via a Unix-domain socket.
925+
</para>
926+
</listitem>
927+
</varlistentry>
928+
929+
<varlistentry id="guc-tcp-keepalives-count" xreflabel="tcp_keepalives_count">
930+
<term><varname>tcp_keepalives_count</varname> (<type>integer</type>)</term>
931+
<indexterm>
932+
<primary><varname>tcp_keepalives_count</> configuration parameter</primary>
933+
</indexterm>
934+
<listitem>
935+
<para>
936+
On systems that support the TCP_KEEPCNT socket option, specifies how
937+
many keepalives may be lost before the connection is considered dead.
938+
A value of 0 uses the system default. If TCP_KEEPINTVL is not
939+
supported, this parameter must be 0.
940+
</para>
941+
</listitem>
942+
</varlistentry>
943+
897944
</variablelist>
898945
</sect3>
899946
<sect3 id="runtime-config-connection-security">

src/backend/libpq/pqcomm.c

Lines changed: 211 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
3131
* Portions Copyright (c) 1994, Regents of the University of California
3232
*
33-
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.176 2005/02/22 04:35:57 momjian Exp $
33+
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.177 2005/07/30 15:17:20 momjian Exp $
3434
*
3535
*-------------------------------------------------------------------------
3636
*/
@@ -87,7 +87,7 @@
8787
#include "libpq/libpq.h"
8888
#include "miscadmin.h"
8989
#include "storage/ipc.h"
90-
90+
#include "utils/guc.h"
9191

9292
/*
9393
* Configuration options
@@ -594,6 +594,19 @@ StreamConnection(int server_fd, Port *port)
594594
elog(LOG, "setsockopt(SO_KEEPALIVE) failed: %m");
595595
return STATUS_ERROR;
596596
}
597+
598+
/* Set default keepalive parameters. This should also catch
599+
* misconfigurations (non-zero values when socket options aren't
600+
* supported)
601+
*/
602+
if (pq_setkeepalivesidle(tcp_keepalives_idle, port) != STATUS_OK)
603+
return STATUS_ERROR;
604+
605+
if (pq_setkeepalivesinterval(tcp_keepalives_interval, port) != STATUS_OK)
606+
return STATUS_ERROR;
607+
608+
if (pq_setkeepalivescount(tcp_keepalives_count, port) != STATUS_OK)
609+
return STATUS_ERROR;
597610
}
598611

599612
return STATUS_OK;
@@ -1158,3 +1171,199 @@ pq_endcopyout(bool errorAbort)
11581171
/* in non-error case, copy.c will have emitted the terminator line */
11591172
DoingCopyOut = false;
11601173
}
1174+
1175+
int
1176+
pq_getkeepalivesidle(Port *port)
1177+
{
1178+
#ifdef TCP_KEEPIDLE
1179+
if (IS_AF_UNIX(port->laddr.addr.ss_family))
1180+
return 0;
1181+
1182+
if (port->keepalives_idle != 0)
1183+
return port->keepalives_idle;
1184+
1185+
if (port->default_keepalives_idle == 0)
1186+
{
1187+
socklen_t size = sizeof(port->default_keepalives_idle);
1188+
if (getsockopt(port->sock, SOL_TCP, TCP_KEEPIDLE,
1189+
(char *) &port->default_keepalives_idle,
1190+
&size) < 0)
1191+
{
1192+
elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
1193+
return -1;
1194+
}
1195+
}
1196+
1197+
return port->default_keepalives_idle;
1198+
#else
1199+
return 0;
1200+
#endif
1201+
}
1202+
1203+
int
1204+
pq_setkeepalivesidle(int idle, Port *port)
1205+
{
1206+
if (IS_AF_UNIX(port->laddr.addr.ss_family))
1207+
return STATUS_OK;
1208+
1209+
#ifdef TCP_KEEPIDLE
1210+
if (idle == port->keepalives_idle)
1211+
return STATUS_OK;
1212+
1213+
if (port->default_keepalives_idle == 0)
1214+
{
1215+
if (pq_getkeepalivesidle(port) < 0)
1216+
return STATUS_ERROR;
1217+
}
1218+
1219+
if (idle == 0)
1220+
idle = port->default_keepalives_idle;
1221+
1222+
if (setsockopt(port->sock, SOL_TCP, TCP_KEEPIDLE,
1223+
(char *) &idle, sizeof(idle)) < 0)
1224+
{
1225+
elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
1226+
return STATUS_ERROR;
1227+
}
1228+
1229+
port->keepalives_idle = idle;
1230+
#else
1231+
if (idle != 0)
1232+
{
1233+
elog(LOG, "setsockopt(TCP_KEEPIDLE) not supported");
1234+
return STATUS_ERROR;
1235+
}
1236+
#endif
1237+
1238+
return STATUS_OK;
1239+
}
1240+
1241+
int
1242+
pq_getkeepalivesinterval(Port *port)
1243+
{
1244+
#ifdef TCP_KEEPINTVL
1245+
if (IS_AF_UNIX(port->laddr.addr.ss_family))
1246+
return 0;
1247+
1248+
if (port->keepalives_interval != 0)
1249+
return port->keepalives_interval;
1250+
1251+
if (port->default_keepalives_interval == 0)
1252+
{
1253+
socklen_t size = sizeof(port->default_keepalives_interval);
1254+
if (getsockopt(port->sock, SOL_TCP, TCP_KEEPINTVL,
1255+
(char *) &port->default_keepalives_interval,
1256+
&size) < 0)
1257+
{
1258+
elog(LOG, "getsockopt(TCP_KEEPINTVL) failed: %m");
1259+
return -1;
1260+
}
1261+
}
1262+
1263+
return port->default_keepalives_interval;
1264+
#else
1265+
return 0;
1266+
#endif
1267+
}
1268+
1269+
int
1270+
pq_setkeepalivesinterval(int interval, Port *port)
1271+
{
1272+
if (IS_AF_UNIX(port->laddr.addr.ss_family))
1273+
return STATUS_OK;
1274+
1275+
#ifdef TCP_KEEPINTVL
1276+
if (interval == port->keepalives_interval)
1277+
return STATUS_OK;
1278+
1279+
if (port->default_keepalives_interval == 0) {
1280+
if (pq_getkeepalivesinterval(port) < 0)
1281+
return STATUS_ERROR;
1282+
}
1283+
1284+
if (interval == 0)
1285+
interval = port->default_keepalives_interval;
1286+
1287+
if (setsockopt(port->sock, SOL_TCP, TCP_KEEPINTVL,
1288+
(char *) &interval, sizeof(interval)) < 0)
1289+
{
1290+
elog(LOG, "setsockopt(TCP_KEEPINTVL) failed: %m");
1291+
return STATUS_ERROR;
1292+
}
1293+
1294+
port->keepalives_interval = interval;
1295+
#else
1296+
if (interval != 0)
1297+
{
1298+
elog(LOG, "setsockopt(TCP_KEEPINTVL) not supported");
1299+
return STATUS_ERROR;
1300+
}
1301+
#endif
1302+
1303+
return STATUS_OK;
1304+
}
1305+
1306+
int
1307+
pq_getkeepalivescount(Port *port)
1308+
{
1309+
#ifdef TCP_KEEPCNT
1310+
if (IS_AF_UNIX(port->laddr.addr.ss_family))
1311+
return 0;
1312+
1313+
if (port->keepalives_count != 0)
1314+
return port->keepalives_count;
1315+
1316+
if (port->default_keepalives_count == 0)
1317+
{
1318+
socklen_t size = sizeof(port->default_keepalives_count);
1319+
if (getsockopt(port->sock, SOL_TCP, TCP_KEEPCNT,
1320+
(char *) &port->default_keepalives_count,
1321+
&size) < 0)
1322+
{
1323+
elog(LOG, "getsockopt(TCP_KEEPCNT) failed: %m");
1324+
return -1;
1325+
}
1326+
}
1327+
1328+
return port->default_keepalives_count;
1329+
#else
1330+
return 0;
1331+
#endif
1332+
}
1333+
1334+
int
1335+
pq_setkeepalivescount(int count, Port *port)
1336+
{
1337+
if (IS_AF_UNIX(port->laddr.addr.ss_family))
1338+
return STATUS_OK;
1339+
1340+
#ifdef TCP_KEEPCNT
1341+
if (count == port->keepalives_count)
1342+
return STATUS_OK;
1343+
1344+
if (port->default_keepalives_count == 0) {
1345+
if (pq_getkeepalivescount(port) < 0)
1346+
return STATUS_ERROR;
1347+
}
1348+
1349+
if (count == 0)
1350+
count = port->default_keepalives_count;
1351+
1352+
if (setsockopt(port->sock, SOL_TCP, TCP_KEEPCNT,
1353+
(char *) &count, sizeof(count)) < 0)
1354+
{
1355+
elog(LOG, "setsockopt(TCP_KEEPCNT) failed: %m");
1356+
return STATUS_ERROR;
1357+
}
1358+
1359+
port->keepalives_count = count;
1360+
#else
1361+
if (count != 0)
1362+
{
1363+
elog(LOG, "setsockopt(TCP_KEEPCNT) not supported");
1364+
return STATUS_ERROR;
1365+
}
1366+
#endif
1367+
1368+
return STATUS_OK;
1369+
}

0 commit comments

Comments
 (0)