postgresql 如何使用SQLAlchemy和Postgres克服2小时连接超时(操作错误)?

zvokhttg  于 2023-01-08  发布在  PostgreSQL
关注(0)|答案(1)|浏览(334)

我尝试使用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,这意味着没有设置限制。

brccelvz

brccelvz1#

我同意@jjanes的观点。这闻起来像是TCP连接超时的问题。可能是网络层的某个地方,不管是NAT还是防火墙,掉了你的TCP连接,让代码等待完整的TCP keepalive超时,直到它看到连接关闭。2当客户端和数据库之间的网络拓扑结构复杂时,通常会发生这种情况。例如,可能有一个公司防火墙,或某种互连。pgAdmin可能带有一个预先配置的设置TCP keepalive,因此它没有受到影响,但我不确定。
其他超时没有起作用,因为在我的理解中,TCP超时在L4层,它掩盖了L7应用程序层中的其他超时。
您可以尝试将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

相关问题