首页 > 数据库 >TCP KEEPALIVE以获得更好的POSTGRESQL体验进程

TCP KEEPALIVE以获得更好的POSTGRESQL体验进程

时间:2023-09-01 23:33:47浏览次数:44  
标签:POSTGRESQL TCP KEEPALIVE PostgreSQL 服务器 keepalive 连接 客户端

如果您听说过 TCP keepalive 但不确定它是什么,请继续阅读。如果您曾经对以下错误消息感到惊讶:

  • server closed the connection unexpectedly
  • SSL SYSCALL error: EOF detected
  • unexpected EOF on client connection
  • could not receive data from client: Connection reset by peer

那么这篇文章适合您。

连接断开的原因

连接断开的可能原因有多种:

数据库服务器崩溃

上面列表中的前两条消息可能是 PostgreSQL 服务器问题造成的。如果服务器由于某种原因崩溃,您将看到类似的消息。要调查服务器是否存在问题,您应该首先查看 PostgreSQL 日志,看看是否可以找到匹配的崩溃报告。

下面我们不会处理这种情况,因为这不是网络问题。

客户端放弃的连接

如果客户端在没有正确关闭数据库连接的情况下退出,服务器在网络套接字上通信时将收到文件结束或错误。通过v14 中引入的新会话统计信息,您可以跟踪 中此类“废弃”数据库连接的数量pg_stat_database.sessions_abandoned

例如,如果应用程序服务器发生故障并重新启动,它通常不会关闭与数据库服务器的连接。这并不令人担忧,当服务器尝试向客户端发送

数据时,数据库服务器会很快检测到它。但如果数据库会话空闲,服务器进程正在等待客户端发送下一条语句(可以看到pg_stat_activity

wait_event)。那么服务器不会立即注意到客户端不再存在!这种挥之不去的后端进程会占用一个进程槽,并可能导致您超出

max_connections

PostgreSQL v14 引入了一个新参数idle_session_timeout,该参数会在一段时间后关闭空闲连接。但这也会终止“健康”的空闲连接,

因此这不是一个很好的解决方案。TCP keepalive 为这个问题提供了更好的解决方案。

网络组件关闭的连接

有时,数据库连接的两端都会遇到相同的问题:每一端都看到另一端“挂断了它们”。在这种情况下,问题出在数据库客户端和服务器之

间。

如果确实存在连接问题,网络连接可能会断开。在软件层面上你无法改变这一点。但很多时候,断开连接是由防火墙或路由器的配置方式

引起的。网络组件可能必须“记住”每个打开连接的状态,而其资源是有限的。因此,“忘记”并删除闲置较长时间的连接似乎是权宜之计。

由于当今的许多 TCP 流量都是通过 HTTP 进行的,并且 HTTP 是无状态的,因此这通常不是问题。如果您的 HTTP 连接断开,您只需为下

一个请求建立一个新连接,这并不是很昂贵。但数据库不同:

  • 建立数据库连接的成本很高
  • 数据库连接不是无状态的;例如,通过关闭连接,您会丢失打开的事务、临时表和准备好的语句
  • 数据库会话空闲较长时间是正常的,例如,如果您正在使用连接池,或者当客户端正在等待长时间运行的分析查询的结果时

这就是TCP持久连接发挥作用的地方,它可以用来保持空闲连接打开。

什么是 TCP keepalive?

Keepalive 是 TCP 协议的一项功能。当您在 TCP 网络套接字上设置该SO_KEEPALIVE选项时,一旦套接字空闲,计时器就会开始运行。当

保活空闲时间到期且套接字上没有进一步活动时,内核将向通信对方发送“保活数据包”。如果对方应答,则认为连接良好,并且计时器再

次开始运行。

如果没有应答,内核在发送另一个持久连接分组之前,会等待持久连接间隔时间。此过程重复进行,直到发送的keepalive报文数量达到

keepalive计数。之后,该连接被视为死亡连接,试图使用该网络套接字将导致错误。

注意,发送keepalive消息的是操作系统内核,而不是应用程序(数据库服务器或客户端)。应用程序不知道这个过程。

TCP keepalive 有两个目的:

  • 防止网络连接处于空闲状态
  • 检测通信的另一端是否离开而没有关闭网络连接

TCP 保活默认设置

keepalive 参数的默认值因操作系统而异。在 Linux 和 Windows 上,默认值为:

  • keepalive 空闲时间:Linux、MacOS 和 Windows 上为 2 小时
  • keepalive 间隔:Linux 和 MacOS 上为 75 秒,Windows 上为 1 秒
  • keepalive 计数:MacOS 上为 8,Linux 上为 9,Windows 上为 10(该值在 Windows 上无法更改)

使用 TCP keepalive 使空闲数据库会话保持活动状态

为了防止防火墙和路由器关闭空闲连接,我们需要为持久连接空闲时间设置一个低得多的值。然后在连接关闭之前发送keepalive报文。

即使数据库客户端和服务器都没有发送任何数据,这也会让出错的网络组件相信连接没有空闲。

对于这种情况,keepalive计数和keepalive间隔是不相关的。我们所需要的就是让第一个keepalive数据包足够早地发送。

使用 TCP keepalive 检测死连接

对于这种情况,减少持久连接空闲时间通常是不够的。如果服务器以75秒的间隔发送9个keepalive报文,则需要超过10分钟才能检测到死

连接。所以我们也会减少keepalive计数,或者keepalive间隔,或者两者都减少——就像在这个例子中一样。

还有一个问题没有解决:即使操作系统检测到网络连接中断,数据库服务器也不会注意到,除非它尝试使用网络套接字。如果它正在等待

客户端的请求,请求会立即执行。但是如果服务器忙于执行一个长时间运行的SQL语句,它不会注意到死亡连接,直到查询完成并尝试将

结果返回给客户端!为了防止这种情况发生,PostgreSQL v14引入了新的参数client_connection_check_interval,该参数目前只在

Linux上支持。设置此参数会导致服务器定期“轮询”套接字,即使它还没有要发送的内容。这样,它可以检测到关闭的连接并中断SQL语句

的执行。

在 PostgreSQL 服务器上设置 TCP keepalive 参数

PostgreSQL 服务器总是设置SO_KEEPALIVETCP 套接字来检测断开的连接,但默认的两小时空闲超时非常长。

您可以设置配置参数tcp_keepalives_idletcp_keepalives_intervaltcp_keepalives_count(Windows 上不支持最后一

项)来更改所有服务器套接字的设置。

这是为所有数据库连接配置TCP keepalive的最方便的方法,而不管使用的客户端是什么。

在PostgreSQL客户端上设置TCP keepalive参数

PostgreSQL 客户端共享库libpq具有连接参数keepalives_idle,keepalives_intervalkeepalives_count(同样,后者在

Windows 上不受支持)来在客户端配置 keepalive。

这些参数可以在PostgreSQL连接字符串中与所有与 libpq链接的客户端接口一起使用,例如Psycopg或PHP。

PostgreSQL JDBC驱动程序不使用libpq,它只有一个连接参数 tcpKeepAlive 来启用TCP keepalive(默认是禁用的),但没有配置

keepalive 空闲时间和其他keepalive设置的参数。

在操作系统上设置TCP keepalive参数

您可以更改操作系统对所有TCP连接的默认值,而不是专门为PostgreSQL连接配置keepalive设置——如果您使用的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

在旧的MacOS版本上,您也可以编辑/etc/sysctl.conf,但参数不同:

# detect dead connections after 70 seconds
net.inet.tcp.keepidle = 60000
net.inet.tcp.keepintvl = 5000
net.inet.tcp.keepcnt = 3

在较新的 MacOS 版本(在 13 上测试)上,创建文件/Library/LaunchDaemons/sysctl.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>sysctl</string>
    <key>Program</key>
    <string>/usr/sbin/sysctl</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/sbin/sysctl</string>
        <string>net.inet.tcp.keepidle=60000</string>
        <string>net.inet.tcp.keepintvl=5000</string>
        <string>inet.inet.tcp.keepcnt=3</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

您必须重新启动才能激活更改。

在 Windows 上,您可以通过添加以下注册表项来更改 TCP keepalive 设置:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveTime
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveInterval

如上所述,没有设置 keepalive 探测的数量,该数量被硬编码为 10。注册表项必须为 DWORD类型,并且值的单位是毫秒而不是秒。

更改这些键后,重新启动 Windows 以激活它们。

结论

配置TCP keepalive连接可以改善PostgreSQL体验,可以保持空闲的数据库连接处于打开状态,也可以及时检测断开的连接。您可以在

PostgreSQL客户端、服务器或操作系统上配置keepalive。

除了配置 keepalive 之外,还可以设置新参数client_connection_check_interval,以便在客户端放弃会话时取消长时间运行的查询。

标签:POSTGRESQL,TCP,KEEPALIVE,PostgreSQL,服务器,keepalive,连接,客户端
From: https://www.cnblogs.com/jl1771/p/17673066.html

相关文章

  • postgresql流复制一(环境搭建)
    PostgreSQL早在9.0版本开始支持物理复制,也可称为流复制(StreamingReplication),通过流复制技术,可以从实例级复制出一个与主库一模一样的从库(也称之为备库)举个简单的例子,在主机host1上创建了一个PostgreSQL实例,并在实例上创建多个数据库,通过流复制技术可以在另外一台主机ho......
  • postgresql流复制三(延迟备库)
    延迟备库是指可以配置备库和主库的延迟时间,这样备库始终和主库保持指定时间的延迟,例如设置备库和主库之间的延迟时间为1小时,理论上备库和主库的延时始终保持在一小时左右。延迟备库1延迟备库的意义PostgreSQL流复制环境下,如果主库不是很忙并且备库硬件资源充分,通常备库和主......
  • postgresql流复制四(查询冲突)
    部署流复制环境后,备库可提供只读操作,通常会将一些执行时间较长的分析任务、统计SQL跑在备库上,从而减轻主库压力,在备库上执行一些长时间SQL时,可能会出现以下错误并被中止:FATAL:terminatingconnectionduetoconflictwithrecoveryDETAIL:Userwasholdingarelation......
  • POSTGRESQL中从MD5到SCRAM-SHA-256
    从v10开始,PostgreSQL提供了scram-sha-256对密码哈希和身份验证的支持。本文介绍了如何安全地调整您的应用程序。为什么我们需要scram-sha-256?PostgreSQL使用哈希加密有两个目的:实际的数据库密码是用户输入的明文密码的哈希值。这可以防止小偷在其他系统上使用偷来的密码。......
  • 用tcpdump抓包做网络分析
    tcpdump不指定任何参数,监听第一块网卡上经过的数据包tcpdump-ieth0监听特定网卡tcpdumphost192.168.0.1监听特定主机的通信包tcpdumpsrchosthostname  特定来源tcpdumpdsthosthostname  特定目标tcpdumpport80           特定端口监听TC......
  • BL110支持BACnet IP、Modbus TCP等多种协议转换
    在工业自动化领域,不同的设备和系统通常采用不同的通信协议进行数据交换。为了实现不同设备之间的无缝连接和数据共享,协议转换网关成为了一种关键的工具。BL110是一款功能强大的协议转换网关,能够实现多种协议之间的转换,包括PLC协议、ModbusRTU、ModbusTCP、DL/T645、IEC101、IEC10......
  • Linux tcp连接数监控实战shell脚本
     tcp连接数监控可用于存储维护中前端业务访问量的统计:使用命令netstat-anpProto:表示协议类型,Recv-Q:表示收包数量, Send-Q:表示发包数量实战示例:#!/bin/bash#thisscriptisusedforcountthequantityofsessionoverstocklog=/ap/log/session_overstock_count.loglog......
  • postgresql常用命令
    PostgreSQL是一个强大的开源关系型数据库管理系统,它提供了许多用于管理数据库和执行操作的命令。以下是一些常用的PostgreSQL命令:连接到数据库:psql-hhostname-ddbname-Uusername这个命令用于连接到指定的数据库,需要提供主机名、数据库名和用户名。你可以根据需要修......
  • 简单描述下HTTP协议和TCP协议之间的关系以及TCP三次握手, 四次挥手
    TCP三次握手,四次挥手TCP(传输控制协议)是一种用于在计算机网络中建立可靠连接的协议。TCP连接的建立和终止分别使用了"三次握手"和"四次挥手"的过程。三次握手:-第一步:客户端发送一个带有SYN(同步)标志的TCP数据包,请求建立连接。-第二步:服务器收到请求后,回复一个带有SYN和ACK(确......
  • Linux安装PostgreSql
    1、准备工作Linux、Centos7、PostgreSql142、安装a>进入PostgreSql下载官网(PostgreSql),选装指定的版本编辑b>依次执行网页中的命令编辑3、设置允许远程连接a>进入data目录[root@localhost~]#cd/var/lib/pgsql/14/datab>修改postgresql.conf文件[root@localhostdata]#vimpo......