PostgreSQL 中的失效连接处理 - Amazon Aurora

PostgreSQL 中的失效连接处理

当客户端应用程序已放弃或异常终止,但数据库会话在服务器上仍保持活动状态时,就会出现失效连接。当客户端进程崩溃或意外终止,但没有正确地关闭其数据库连接或取消正在进行的请求时,通常会出现这种情况。

当服务器进程处于空闲状态或试图向客户端发送数据时,PostgreSQL 可以高效地识别和清理失效连接。但是,对于处于空闲状态、等待客户端输入或当前正在运行查询的会话,检测过程颇具挑战性。为了处理这些情况,PostgreSQL 提供了 tcp_keepalives_*tcp_user_timeoutclient_connection_check_interval 参数。

了解 TCP keepalive

TCP Keepalive 是一种协议级机制,有助于保持和验证连接完整性。每个 TCP 连接都保持内核级别的设置,这些设置控制着 keepalive 行为。当 keepalive 计时器到期时,系统会执行以下操作:

  • 发送一个没有数据且设置了 ACK 标志的探测数据包。

  • 根据 TCP/IP 规范,期待来自远程端点的响应。

  • 根据响应或无响应来管理连接状态。

Aurora PostgreSQL 中的关键 TCP keepalive 参数

参数 描述 默认值
tcp_keepalives_idle Specifies number of seconds of inactivity before sending keepalive message. 300
tcp_keepalives_interval Specifies number of seconds between retransmissions of unacknowledged keepalive messages. 30
tcp_keepalives_count Maximum lost keepalive messages before declaring connection dead 2
tcp_user_timeout Specifies how long (in Milliseconds) unacknowledged data can remain before forcibly closing the connection. 0
client_connection_check_interval Sets the interval (in Milliseconds) for checking client connection status during long-running queries. This ensures quicker detection of closed connections. 0

TCP keepalive 设置的使用案例

使空闲会话保持连接状态

为防止空闲连接因处于非活动状态而被防火墙或路由器终止:

  • 配置 tcp_keepalives_idle 定期发送 keepalive 数据包。

检测失效连接

要迅速检测失效连接:

  • 调整 tcp_keepalives_idletcp_keepalives_intervaltcp_keepalives_count。例如,使用 Aurora PostgreSQL 默认值,检测到失效连接大约需要一分钟(2 次探测 × 30 秒)。降低这些值可以加快检测速度。

  • 使用 tcp_user_timeout 来指定等待确认的最长时间。

TCP keepalive 设置有助于内核检测失效连接,但在使用套接字之前,PostgreSQL 可能无法执行操作。如果会话正在运行长时间的查询,则可能只有在查询完成后才能检测到失效连接。在 PostgreSQL 14 及更高版本中,client_connection_check_interval 可以通过在查询执行期间定期轮询套接字来加快失效连接检测。

最佳实践

  • 设置合理的 keepalive 间隔:调整 tcp_user_timeouttcp_keepalives_idletcp_keepalives_counttcp_keepalives_interval,以平衡检测速度与资源用量。

  • 针对环境进行优化:使设置与网络行为、防火墙策略和会话需求相一致。

  • 利用 PostgreSQL 功能:在 PostgreSQL 14 及更高版本中使用 client_connection_check_interval 来进行高效的连接检查。