PostgreSQL 中的失效连接处理
当客户端应用程序已放弃或异常终止,但数据库会话在服务器上仍保持活动状态时,就会出现失效连接。当客户端进程崩溃或意外终止,但没有正确地关闭其数据库连接或取消正在进行的请求时,通常会出现这种情况。
当服务器进程处于空闲状态或试图向客户端发送数据时,PostgreSQL 可以高效地识别和清理失效连接。但是,对于处于空闲状态、等待客户端输入或当前正在运行查询的会话,检测过程颇具挑战性。为了处理这些情况,PostgreSQL 提供了 tcp_keepalives_*
、tcp_user_timeout
和 client_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_idle
、tcp_keepalives_interval
和tcp_keepalives_count
。例如,使用 Aurora PostgreSQL 默认值,检测到失效连接大约需要一分钟(2 次探测 × 30 秒)。降低这些值可以加快检测速度。 -
使用
tcp_user_timeout
来指定等待确认的最长时间。
TCP keepalive 设置有助于内核检测失效连接,但在使用套接字之前,PostgreSQL 可能无法执行操作。如果会话正在运行长时间的查询,则可能只有在查询完成后才能检测到失效连接。在 PostgreSQL 14 及更高版本中,client_connection_check_interval
可以通过在查询执行期间定期轮询套接字来加快失效连接检测。
最佳实践
-
设置合理的 keepalive 间隔:调整
tcp_user_timeout
、tcp_keepalives_idle
、tcp_keepalives_count
和tcp_keepalives_interval
,以平衡检测速度与资源用量。 -
针对环境进行优化:使设置与网络行为、防火墙策略和会话需求相一致。
-
利用 PostgreSQL 功能:在 PostgreSQL 14 及更高版本中使用
client_connection_check_interval
来进行高效的连接检查。