一款Windows PC端待办事项软件
登录   注册


Python用psycopg2连接PostgreSQL时server closed the connection unexpectedly



Psycopg2是Python连接到PostgreSQL的常用模块。我使用它时遇到了一个问题:当使用一个已经空闲一段时间的connection时,会有以下异常出现:

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

经过一段时间的网上搜索,我发现似乎有两个原因可能导致它。而第二个原因很少被提及:

  • 这是Psycopg2在2.8.1之前版本的一个bug,已经在新版本中修复:https://github.com/psycopg/psycopg2/issues/829

  • 创建connection时未使用有关保持连接活动的参数。

请参见以下代码:

conn = psycopg2.connect(database="DBname",
                        host="Your_IP_address",
                        user="username",
                        password="Your_password",
                        port=5432,
                        keepalives=1, # 保持连接
                        keepalives_idle=130, # 空闲时,每130秒保持连接连通
                        keepalives_interval=10, # 没得到回应时,等待10秒重新尝试保持连通
                        keepalives_count=15 # 尝试最多15次重新保持连通
                        )

我添加最后四个参数后问题就消失了。正是这些参数定义了connection应该如何keep-alive。

Keepalives=1,这使得连接试图保持活动状态,其方式由其余3个参数定义。

keepalives_idle,定义连接处于空闲状态多久后,发送keep-alive信息到服务器。

keepalives_interval,定义如果服务器没有回应keep-alive消息,模块应重试多长时间。

keepalives_count,定义如果先前的keep-alive消息在放弃之前没有成功,那么模块应该重试多少次。

我没有看到psycopg2的文档中特地介绍这些keep-alive参数,但提到了:

“Any other connection parameter supported by the client library/server can be passed either in the connection string or as a keyword. The PostgreSQL documentation contains the complete list of the "https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS" supported parameters. Also note that the same parameters can be passed to the client library using "https://www.postgresql.org/docs/current/static/libpq-envars.html" environment variables.”

所以这些参数实际上是由PosgreSQL客户端库定义和接受的。这些keep-alive参数,和更多的参数,可以在PostgreSQL文档中查到:




老周PMP博客