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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy