【问题标题】:How to overcome the 2hr connection timeout (OperationalError) using SQLAlchemy and Postgres?如何使用 SQLAlchemy 和 Postgres 克服 2 小时连接超时(OperationalError)?
【发布时间】:2023-01-05 12:37:14
【问题描述】:

我正在尝试使用 SQLAlchemy 针对托管在 AWS RDS 上的 Postgres 数据库执行一些长时间运行的 SQL 查询。

from sqlalchemy import create_engine
conn_str = 'postgresql://user:password@db-primary.cluster-cxf.us-west-2.rds.amazonaws.com:5432/dev'
engine = create_engine(conn_str)

sql = 'UPDATE "Clients" SET "Name" = NULL'
#this takes about 4 hrs to execute if run in pgAdmin
with engine.begin() as conn:
    conn.execute(sql)

运行正好 2 小时后,脚本出现错误

OperationalError: server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.

(Background on this error at: https://sqlalche.me/e/14/e3q8)

我已经测试了在 SQLAlchemy 中设置连接超时(基于How to set connection timeout in SQLAlchemy)。这并没有什么不同。

我查看了 Postgres 设置中的连接设置(基于 https://dba.stackexchange.com/questions/164419/is-it-possible-to-limit-timeout-on-postgres-server),但是 statement_timeoutidle_in_transaction_session_timeout 都设置为 0,这意味着没有设置限制。

【问题讨论】:

  • 这怎么可能?即使有一亿条记录,那也应该是 10 秒的操作,而不是 4 小时的操作。
  • 我刚刚添加了一个虚拟示例 sql 语句,实际的 SQL 语句只有一页半长,但在 pgAdmin/DBeaver 中运行时没有任何问题。我认为特定的 SQL 语句对手头的问题没有任何影响。
  • 一些防火墙/路由器可能被配置为在一段时间(他们认为是)不活动后断开连接。
  • 2 小时听起来像是 tcp 超时。尝试设置 tcp keep alive 值。
  • @jjanes 应该在运行 python 代码的客户端上还是在 postgres 服务器上设置这些?如果是后者,为什么 SQL 语句在 pgAdmin 中没有任何问题地工作?

标签: python postgresql sqlalchemy amazon-rds


【解决方案1】:

我同意@jjanes。这听起来像是 TCP 连接超时问题。可能是在网络层的某个地方,无论是 NAT 还是防火墙,丢弃了您的 TCP 连接,让代码等待完整的 TCP keepalive 超时,直到它看到连接已关闭。当客户端和数据库之间的网络拓扑复杂时,通常会发生这种情况。例如,可能有公司防火墙或某种互连。 pgAdmin 可能带有 TCP keepalive 的预配置设置,因此它没有受到影响,但我不确定。

您可以尝试将 keepalive 参数添加到您的连接字符串中,看看它是否可以解决问题。例如:

postgresql://user:password@db-primary.cluster-cxf.us-west-2.rds.amazonaws.com:5432/dev?keepalives_idle=1&keepalives_count=1&tcp_user_timeout=1000

注意最后的keepalive参数。供您参考,以下是对这些参数的解释: https://www.postgresql.org/docs/current/runtime-config-connection.html

【讨论】:

    猜你喜欢
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2021-01-29
    • 2021-01-12
    • 1970-01-01
    • 2019-12-28
    • 2013-11-01
    相关资源
    最近更新 更多