重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 108|回复: 0
打印 上一主题 下一主题

postgresql通信连接的方方面面

[复制链接]
跳转到指定楼层
楼主
发表于 2026-2-8 20:00:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、会话保持
1.0通信方式的概念
Unix、UDP、TCP

Unix 套接字、UDP 套接字和 TCP 套接字是三种不同的套接字类型,它们的主要区别在于通信方式、使用场景以及协议栈的不同。让我们逐一了解它们的区别:
### 1. Unix 套接字 (Unix Domain Socket)
类型:用于同一台机器上的进程间通信(IPC,Inter-Process Communication)。
协议:不使用网络协议栈,而是直接在内核中通过文件系统进行通信。
特性:

   速度快:因为它直接在内核空间进行数据传输,不需要通过网络层,所以比网络套接字(如 TCP 或 UDP)要快。
   本地通信:只能用于同一台计算机上的不同进程之间的通信,不适用于网络上的分布式系统。
   路径:通过文件系统路径来标识(例如:`/tmp/.s.PGSQL.5432` 是 PostgreSQL 的 Unix 套接字)。
应用:

   适用于同一主机上的进程之间的通信,尤其是当你想减少网络开销时。例如,数据库服务器和客户端可能通过 Unix 套接字进行通信。

### 2. UDP 套接字 (User Datagram Protocol Socket)

类型:基于无连接的协议,适用于需要快速数据传输且对数据传输顺序和完整性不那么严格的场景。
协议:UDP 是一种无连接的协议,数据包独立发送,数据包之间没有顺序保证,也没有重传机制。它位于传输层,直接基于 IP 协议工作。
特性:

   无连接:发送数据前不需要建立连接,也不会保证数据包到达对方或者按顺序到达。
   低延迟:由于不需要建立连接、确认接收等步骤,UDP 通常比 TCP 快。
   不可靠:不保证数据的可靠传输,丢包和乱序可能会发生。
应用:

   适用于实时性要求高、可以容忍一定丢包的场景,如视频流、语音通信、在线游戏等。

### 3. TCP 套接字 (Transmission Control Protocol Socket)

类型:基于有连接的协议,适用于需要可靠传输、确保数据顺序且数据完整性的场景。
协议:TCP 是一种面向连接的协议,数据在传输过程中会进行分段、重组、校验,保证数据可靠传输。它位于传输层。
特性:

   连接导向:在发送数据之前,必须先建立连接(三次握手),数据传输过程中保持连接。
   可靠性:保证数据的顺序、完整性和可靠性,通过确认机制、重传机制、流量控制等手段来确保数据不会丢失或乱序。
   较慢:由于需要连接建立、确认接收等步骤,TCP 的延迟比 UDP 高。
应用:

   适用于需要保证数据可靠传输的应用,如文件传输、网页浏览、电子邮件等。

### PostgreSQL 中的使用:

Unix 套接字:在同一台机器上,PostgreSQL 默认使用 Unix 套接字与客户端通信。这样可以减少网络延迟,提高本地通信效率。
TCP 套接字:当 PostgreSQL 被配置为允许远程连接时,客户端和数据库服务器之间通过 TCP 套接字通信,通常使用端口(如 5432)来建立连接。
UDP 套接字:一般不常用于数据库通信,除非用于某些特定的网络应用(例如 DNS 查询、广播等)。在 PostgreSQL 中,可能用于某些辅助功能,但通常不会用于实际的数据库查询传输。
总结:主要区别

特性        Unix 套接字        UDP 套接字        TCP 套接字
连接方式        无连接(本地进程间通信)        无连接(数据包独立发送)        有连接(需要三次握手)
数据可靠性        高(本地通信,没有丢失)        低(无保障,可能丢失数据)        高(保证顺序,可靠传输)
传输速度        非常快(本地)        快,但没有顺序保证和重传机制        较慢(因为需要建立连接和确认)
适用场景        同一机器上的进程间通信        实时、低延迟要求较高、能容忍丢包的场景        需要可靠传输的场景
常见应用        本地进程间通信(如数据库)        视频流、在线游戏、DNS 查询等        网页浏览、文件传输、电子邮件等
协议层次        操作系统内核层        网络层(UDP/IP 协议)        网络层(TCP/IP 协议)
1.1pg连接的参数
pg数据库中关于事务连接的一些参数:

1.statement_timeout:
用来控制语句执行时长,单位是ms(可以显示指定)。默认是0,表示语句可以一直执行下去。建议设置为0。可以会话级设置。如果一个简单查询消息中包含多个 SQL 语句,则超时会分别应用于每个语句。

2.idle_in_transaction_session_timeout:
用来控制事务执行时长,自动查杀超过指定时间的idle in transaction空闲事务连接,用于清理应用代码中忘记关闭已开启的事务,或者系统中存在僵死进程等,单位是ms,默认值是0,不开启。注意:该参数对idle正常连接无影响。

3.idle_session_timeout:
该参数设置一个会话空闲超时时间,用来控制在没有任何活动的情况下,连接可以保持空闲多久。如果空闲时间超过该时间,连接将被终止。

4.log_statement 和 log_connections:
虽然这两个参数不直接控制空闲连接,但它们用于记录连接的活动和状态。通过日志,可以监控是否有大量空闲连接,从而采取进一步措施。

长链接的危害不言而喻,在14以前是没有参数用于控制空闲连接何时主动超时断开的(不要与tcp keepalive机制搞混),当然你可以通过pg_timeout插件或者自己写脚本来更加细粒度地控制,在14就方便了,idle_session_timeout解千愁。

1.2pg_timeout控制空闲连接
可使用扩展插件pg_timeout插件,配置postgresql.conf

shared_preload_libraries = 'pg_timeout'
pg_timeout.naptime=60 #单位为秒
pg_timeout.idle_session_timeout=60 #单位为秒
1.3连接检测
1.3.1OS中相关参数
TCP_KEEPCNT、TCP_KEEPIDLE、TCP_KEEPINTVL这三个参数属于 Linux 内核 TCP 协议栈的 socket 选项(per-socket),在 setsockopt() 中通过 IPPROTO_TCP 级别设置,优先级高于 /proc/sys/net/ipv4/tcp_keepalive_* 的全局默认值。
TCP_KEEPCNT   (keepalive计数,连续发送探测包后,达到该计数设置并没有回应,则认为连接已失效) 覆盖 tcp_keepalive_probes,默认9(次)
TCP_KEEPIDLE  (keepalive空闲时间,超过该设置,发送packet) 覆盖 tcp_keepalive_time,默认7200(秒)
TCP_KEEPINTVL (keepalive间隔时间,发送packet后,没有回应,等待该间隔时间后再次发送) 覆盖 tcp_keepalive_intvl,默认75(秒)
在sysctl.conf中是这样的:

cat /etc/sysctl.conf |grep keep
net.ipv4.tcp_keepalive_intvl=15
net.ipv4.tcp_keepalive_probes=3
net.ipv4.tcp_keepalive_time=1000
对应关系:

TCP_KEEPIDLE     tcp_keepalive_time
TCP_KEEPINTVL    tcp_keepalive_intvl
TCP_KEEPCNT      tcp_keepalive_probes
修改:

查询:
cat /proc/sys/net/ipv4/tcp_keepalive_time
sysctl net.ipv4.tcp_keepalive_time

临时生效:
sysctl -w net.ipv4.tcp_keepalive_time=3600
echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time

重启生效:
修改/etc/sysctl.conf文件
syscyl -p生效
1.3.2postgresql中
查看postgresql.conf
tcp_keepalives_idle = 60
tcp_keepalives_interval = 20
tcp_keepalives_count = 3
--注意:不配置会使用操作系统默认值。

查看:
postgres=# SELECT name, setting FROM pg_settings WHERE name LIKE '%tcp%';
          name           | setting
-------------------------+---------
tcp_keepalives_count    | 9
tcp_keepalives_idle     | 7200
tcp_keepalives_interval | 75
tcp_user_timeout        | 0
(4 rows)
在PostgreSQL中,也有相关的几个参数用于释放无法继续通讯的空闲连接,默认配置取决于操作系统

postgres=# select name,setting from pg_settings where name like 'tcp%';
          name           | setting
-------------------------+---------
tcp_keepalives_count    | 0
tcp_keepalives_idle     | 0
tcp_keepalives_interval | 0
tcp_user_timeout        | 0
(4 rows)
如果通信一方突然崩溃,无法通知对方,此时另一方能做的就只有傻傻等待了,所以引入了keepalive机制,快速感知失败。
但是如果服务端正在忙着处理一个长查询,并不会立马注意到死连接直至查询结束,并且尝试给客户端发送执行结果
在14中引入了client_connection_check_interval参数来解决这个问题,每隔一段时间检查客户端是否已离线,如果离线则快速结束未完成的查询,防止客户端已离线而数据库继续运行未完成的查询。

unix和tcp/ip区别
现象:

$ tail postgresql.auto.conf
Do not edit this file manually!
It will be overwritten by the ALTER SYSTEM command.
port =15432
listen_addresses = '*'
logging_collector = on
archive_command = 'cp %p /home/arch/%f'
shared_preload_libraries = 'pg stat_statements'
tcp_keepalives_idle= 3
tcp_keepalives_interval= 1
tcp_keepalives_count= 1

$ psql
psq1(14.4)
Type "help" for help.
postgres=# show tcp_keepalives idle;
tcp_keepalives_idle
--------------------
0
postgres=i show tcp_keepalives_interval;
tcp_keepalives_interval
--------------------
0
postgres=t show tcp_keepalives_count;
tcp_keepalives_count
--------------------
0
两种方式要以上面的查询值为准:

[postgres@jeromebase ~]$ psql -h 127.0.0.1
psql (16.6)
Type "help" for help.

postgres=# SELECT name, setting FROM pg_settings WHERE name LIKE '%tcp%';
          name           | setting
-------------------------+---------
tcp_keepalives_count    | 9
tcp_keepalives_idle     | 7200
tcp_keepalives_interval | 75
tcp_user_timeout        | 0
(4 rows)

[postgres@jeromebase ~]$ psql
psql (16.6)
Type "help" for help.

postgres=# SELECT name, setting FROM pg_settings WHERE name LIKE '%tcp%';
          name           | setting
-------------------------+---------
tcp_keepalives_count    | 0
tcp_keepalives_idle     | 0
tcp_keepalives_interval | 0
tcp_user_timeout        | 0
(4 rows)
为什么数据库里显式为0?官网说明:

如果是通过unix domain socket登录的话,那么始终显式为0。
unix domain socket不需要使用传统的IP地址和端口,而是使用文件系统来进行程序之间的数据交互,如果不同主机上的两个进程进行通信,使用传统的TCP/IP协议当然没什么问题。
但是,如果只需要在一台机器上的两个不同进程间通信,就有点杀鸡用牛刀的味道了,这便是unix domain socket的缘由。
通过psql -h /path/to/socket/directory/ -p port切换其他目录下的socket文件,所以显式为0就不足为奇了。

当然功能类似的还有jdbc中的socket timeout,可以理解成全局的查询时长限制,是通过TCP连接发送数据(SQL)后,等待响应的超时时间,也可以及时发现网络问题,虽然有了keepalive机制,但大多数操作系统的心跳包的间隔时间要么很长,要不默认没有设置,比如Linux下的keepalive的设置是2小时,所以这个参数也可以帮助我们。
1.4连接断开的原因
连接断开有好几种原因
1.1数据库服务崩溃

上述列表中的前两条消息可能是PostgreSQL自身服务出问题导致的结果。如果服务因任何原因崩溃,你便会看到类似的消息。
要检查服务是否存在问题,你应该首先查看日志,看看是否可以找到匹配的崩溃报告。
我们不会在接下来处理这种情况,因为它不是网络问题。
1.4.2连接被客户端抛弃
如果客户端没有正确关闭数据库连接而退出,服务器会在与网络套接字通信时得到一个end-of-file或一个错误。
在v14中,引入的新的会话统计信息,你可以在pg_stat_database中跟踪这种被抛弃的数据库连接的数量:pg_stat_database.sessions_abandoned.
比如应用服务失败了然后重启,通常情况下它并不会关闭连接到数据库的连接。这并不值得恐慌,因为数据库会在尝试给客户端发送数据的时候检测到。
select * from pg_stat_database;
-[ RECORD 5 ]------------+-----------------
datid                    | 16447
datname                  | ycdm
numbackends              | 201
xact_commit              | 145728149
xact_rollback            | 1889328
blks_read                | 54002238013
blks_hit                 | 1678751771959
tup_returned             | 19387700864010
tup_fetched              | 651729832864
tup_inserted             | 85188589003
tup_updated              | 7009846860
tup_deleted              | 21020331566
conflicts                | 0
temp_files               | 1597130
temp_bytes               | 21145394096566
deadlocks                | 3
checksum_failures        |
checksum_last_failure    |
blk_read_time            | 0
blk_write_time           | 0
session_time             | 445230227784.845
active_time              | 9821921344.39
idle_in_transaction_time | 785562516.629
sessions                 | 479873
sessions_abandoned       | 38994
sessions_fatal           | 141
sessions_killed          | 220
stats_reset              |
但是如果数据库会话处于空闲状态,服务端进程会等待客户端下发下一条语句(你会在pg_stat_activity中看到wait_event是 ClientRead )。
但是服务端不会立马觉察到客户端连接已经不在了!这样的缓慢消失的连接会占用一个连接槽并且可能会导致需要增加max_connections。
在v14版本中,引入了一个新的参数idle_session_timeout,会在一定时间后关闭空闲连接。但是这同样也会杀掉"健康"的空闲连接,因此这并不是一个很好的解决方式。TCP keepalive针对这种问题提供了一个更好的解决方式。

1.4.3由网络组件关闭的连接
有时,数据库连接的两端都会遇到相同的问题:每一端都看到另一端处于挂起的状态。在这种情况下,问题存在于数据库客户端和服务器之间的某个地方。
如果存在真正的连接问题,网络连接可能会断开。在软件层面,你无法改变这一点。但通常情况下,连接断开是由防火墙或路由器的配置方式引起的。
网络组件可能必须"记住"每个打开连接的状态,而这些连接的资源是有限的。因此,"忘记"并删除闲置了较长时间的连接似乎是一种权宜之计。
因为现在很多TCP流量都是通过HTTP的,而且HTTP是无状态的,所以这通常不是问题。如果HTTP连接断开,只需为下一个请求建立一个新的连接,这开销也并不大。
但是数据库是不同的:
数据库连接的特点
•建立一个数据库连接是昂贵的
•数据库连接不是无状态的,例如,在关闭连接的情况下,你会丢失打开的事务、临时表和预备语句
•数据库会话空闲很长一段时间是正常的,例如,如果您正在使用连接池,或者客户端正在等待一个长时间运行的分析查询的结果

这就是TCP keepalive作为一种保持空闲连接打开的方法的用处所在。

二、关于TCP keepalive
什么是TCP keepalive?

1.server closed the connection unexpectedly
服务器意外关闭了连接
这个错误意味着服务器突然关闭了与客户端的连接,可能的原因包括服务器崩溃、超时、或网络问题等。客户端在没有预期的情况下失去了连接。

2.SSL SYSCALL error: EOF detected
SSL 系统调用错误:检测到文件结束符(EOF)
这是一个与 SSL(安全套接层)连接相关的错误,通常发生在使用加密连接时。EOF(End Of File)表示连接被远程方关闭。这个错误表明客户端在尝试与服务器进行 SSL 通信时,服务器意外断开了连接,可能由于网络问题、超时或服务器崩溃等原因。

3.unexpected EOF on client connection
客户端连接意外收到文件结束符(EOF)
这个错误意味着客户端在没有预期的情况下,收到了文件结束符(EOF),即服务器意外地断开了连接。通常这表明服务器在客户端还在等待数据时已经关闭了连接。

4.could not receive data from client: Connection reset by peer
无法从客户端接收数据:连接被对方重置
这个错误表示服务器尝试从客户端读取数据时,连接被远程端(客户端)重置了。Connection reset by peer 意味着客户端主动关闭了连接或者连接中断了,可能是由于客户端崩溃、网络断开或其他故障。
TCP keepalive三个参数:idle time、nterval、count的机制:
1.Keepalive是TCP协议的一种功能。当在TCP套接字上设置了SO_KEEPALIVE的选项后,套接字在空闲时会运行一个计时器。当超过了keepalive idle time,并且套接字上没有进一步的活动时,内核便会向通信对象发送一个keepalive报文。如果对象应答,则认为连接良好,计时器再次开始运行。
2.如果没有应答,内核会等待keepalive interval,然后再发送另外的keepalive报文,重复这个过程.
3.直到发送keepalive报文的数量达到了keepalive count。在那之后,连接便被认为是死的,继续尝试使用套接字会报错。
4.请注意,发送keepalive消息的是操作系统内核,而不是应用程序(数据库服务器或客户端)。应用程序并不知晓这个过程。

TCP keepalive用作两个目的:
•保持网络连接不变成空闲状态
•检测另一个通信端是否已经离开但却没有关闭网络连接("keepalive"这个词并没有描述准确,"detectdead"这个词更加贴切)

2.1keepalive的配置场景
keepalive相关的默认值因操作系统而异。在Linux和Windows上,默认值如下:(具体查看方式在上面已经给出:《### 1.3.1OS中相关参数》 )

  •keepalive idle time:在Linux和Windows上均是2小时
  •keepalive interval :在Linux上是75s,在Windows上是1s
  •keepalive count    :在Linux上是9,在Windows上是10(在Windows上这个值不可修改)
关于MacOS的默认值还不清楚。
(1)确保空闲数据库会话存活
为了防止防火墙和路由器关闭空闲的连接,我们需要配置一个低得多的keepalive idle timeout值。然后在连接关闭之前发送keepalive报文。这将欺骗较为麻烦的网络组件,使其相信连接不是空闲的,即使数据库客户端和服务器都没有发送任何数据。
对于这个用例,keepalive count和keepalive interval无关紧要。我们所需要的只是让第一个keepalive报文足够早地发送出去。

(2)检测死连接
对于这个案例,仅仅减少keepalive idle time的值通常情况下并不足够。如果服务器以75秒为间隔发送了9个keepalive报文,则需要10分钟以上才能检测到死连接。因此,我们还需要减少keepalive count或者keepalive interval,或像本例一样同时减少。
这个谜题还缺一块:即使操作系统检测到了网络连接已断开,数据库服务端并不知道,除非它尝试使用网络套接字。如果它正在等待客户端的请求,可以很快检测到连接断开。但是如果服务端正在忙于处理一个长查询,它并不会注意到死连接直到查询结束,并且尝试给客户端发送执行结果。为了防止这种问题的发生,PostgreSQL14引入了一个新的参数client_connection_check_interval,目前仅在Linux上支持。设置了此参数,服务器会定时"轮询"套接字,即使它还没有任何东西要发送。这样,它就可以检测到一个关闭的连接并中断SQL语句的执行。

(3)pg配置TCP keepalive
PostgreSQL服务端总是会在TCP套接字上设置SO_KEEPALIVE来检测断开的连接,但是默认的空闲超时时间是两个小时(7200),太长了。
可以通过设置参数tcp_keepalives_idle,tcp_keepalives_interval和tcp_keepalives_count(最后一个参数在Windows上不支持)以调整所有的服务套接字。
这是为所有数据库连接配置TCP keepalive的最便捷的方法,无论使用的客户端是什么。

(4)pg客户端设置TCPkeepalive
PostgreSQL 客户端共享库libpq具有连接参数keepalives_idle、keepalives_interval、keepalives_count(同样,后者在Windows 上不受支持)来在客户端配置 keepalive。
这些参数可以在PostgreSQL连接字符串中与所有与libpq链接的客户端接口一起使用,例如Psycopg或PHP。
PostgreSQL JDBC驱动程序不使用libpq,它只有一个连接参数 tcpKeepAlive 来启用TCP keepalive(默认是禁用的),但没有配置keepalive 空闲时间和其他keepalive设置的参数。

连接字符串 中直接指定这些参数
psql "postgresql://test:~Pc~d9K27a=oE3A<P6O@10.206.0.4:5432/testdb?keepalives_idle=600&keepalives_interval=30&keepalives_count=5"
Python 中使用 psycopg2 库来连接 PostgreSQL 数据库
## Python 中使用 `psycopg2` 库来连接 PostgreSQL 数据库
import psycopg2

# 连接字符串包含 keepalive 参数
conn = psycopg2.connect(
    "dbname=test user=postgres password=secret host=localhost port=5432 "
    "keepalives_idle=600 keepalives_interval=30 keepalives_count=5"
)

# 创建一个游标对象
cur = conn.cursor()
cur.execute("SELECT version();")
print(cur.fetchone())

cur.close()
conn.close()
PHP 中,可以通过 pg_connect() 函数使用连接字符串来指定 keepalive参数
<?php
// PostgreSQL 连接字符串包含 keepalive 参数
$conn = pg_connect("host=localhost dbname=test user=postgres password=secret port=5432
                    keepalives_idle=600 keepalives_interval=30 keepalives_count=5");

if ($conn) {
    echo "Connection successful!";
} else {
    echo "Connection failed!";
}

pg_close($conn);
?>
(5)在操作系统上设置TCP keepalive
如果你使用的是不允许设置keepalive连接参数的PostgreSQL客户端应用程序,你可以更改所有TCP连接的操作系统默认值,而不是专门为PostgreSQL连接配置keepalive。
在Linux上,可以编辑/etc/sysctl.conf

# detect dead connections after 70 seconds
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 3
为了在不重启服务器的前提下激活配置,需要执行sysctl -p
在Windows上,您可以通过添加这些注册表项来更改TCP保持连接设置
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveTime
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveInterv
如上所述,keepalive探测的数量没有设置,它被硬编码为10。注册表项必须是DWORD类型,值的单位是毫秒而不是秒。更改这些值后,重新启动Windows以激活它们。
2.2总结
配置TCP keepalive可以提高使用PostgreSQL的体验,要么保持空闲的数据库连接打开,要么通过及时检测断开的连接。你可以在PostgreSQL客户端、服务器或操作系统上配置keepalive。
除了配置keepalive之外,还需要设置新的参数client_connection_check_interval,以便在客户端放弃会话时取消长时间运行的查询。

三、keepalives_* 最大值
日志报错:

2025-07-13 08:25:15.989 CST [2608148] LOG:  setsockopt(TCP_KEEPCNT) failed: Invalid argument  
2025-07-13 08:25:41.874 CST [2608148] LOG:  setsockopt(TCP_KEEPCNT) failed: Invalid argument  
“setsockopt(TCP_KEEPXX)”说明调用 Linux 内核 TCP 协议栈的 socket 选项。
PG代码中当调用 setsockopt返回值小于0,则打印日志“setsockopt(TCP_KEEPXX) failed”
分析setsockopt函数:
setsockopt是glibc函数,通过sys call最终调用到内核态中由do_tcp_setsockopt函数完成对应option设置。
当option为KEEPIDLE时,调用tcp_sock_set_keepidle_locked进行配置,当入参小于1< 或者入参大于MAX_TCP_KEEPIDLE时,返回-EINVAL(EINVAL是Linux/Unix 系统中表示"无效参数"的错误代码,值为22)。MAX_TCP_KEEPIDLE为32767

#define MAX_TCP_KEEPIDLE 32767  
#define MAX_TCP_KEEPINTVL 32767  
#define MAX_TCP_KEEPCNT  127
使用setsockopt进行KEEPIDLE设置时,入参小于1或者大于32767就会返回Invalid argument。
为什么MAX_TCP_KEEPIDLE是32767?

1. 历史原因和兼容性
早期的内核实现中,许多网络相关的参数使用的是 16 位整数(short 类型)来存储值,而 16 位整数的最大值是 32767(即 2^15 - 1)。虽然现代内核已经支持更大的范围,但某些参数的限制仍然保留了这种历史设计,以确保与旧版本的内核或应用程序的兼容性。

2. 实际需求的考虑
tcp_keepalive_time 的作用是设置 TCP 连接在空闲多长时间后开始发送 keepalive 探测包。对于大多数实际场景来说,超过 32767 秒(约 9.1 小时)的空闲时间已经足够长,几乎没有实际需求需要更大的值。因此,限制在 32767 秒可以满足绝大多数使用场景。
实测tcp_keepalives_idle和tcp_keepalives_interval不能大于32767,tcp_keepalives_count不能大于127,若大于则打印 “LOG:  setsockopt(TCP_KEEPXXX) failed: Invalid argument”。

[postgres@Nick ~]$ psql -h 127.0.0.1 -U testuser -d postgres  
psql (18beta1)  
Type "help" for help.  

postgres=> set client_min_messages to log;  
SET  
postgres=> set tcp_keepalives_idle to 32768;  
LOG:  setsockopt(TCP_KEEPIDLE) failed: Invalid argument  
SET  
postgres=> set tcp_keepalives_interval to 32768;  
LOG:  setsockopt(TCP_KEEPINTVL) failed: Invalid argument  
SET  
postgres=> set tcp_keepalives_count to 128;  
LOG:  setsockopt(TCP_KEEPCNT) failed: Invalid argument  
SET  
postgres=> set tcp_keepalives_idle to 32767;  
SET  
postgres=> set tcp_keepalives_interval to 32767;  
SET  
postgres=> set tcp_keepalives_count to 127;  
SET  
postgres=>
但是PG官方给定的这几个keepalive参数最大值为2147483647(int类型),这是为什么?

postgres=> select name,min_val,max_val from pg_settings where name like '%keepalives%';  
          name           | min_val |  max_val     
-------------------------+---------+------------  
tcp_keepalives_count    | 0       | 2147483647  
tcp_keepalives_idle     | 0       | 2147483647  
tcp_keepalives_interval | 0       | 2147483647
总结
parameter        min_val        max_val
tcp_keepalives_count        0        127
tcp_keepalives_idle        0        32767
tcp_keepalives_interval        0        32767


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2026-4-17 18:28 , Processed in 0.304382 second(s), 21 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表