Psycopg / Postgres:连接随机挂出

时间:2010-11-13 15:09:54

标签: python postgresql cherrypy psycopg2

我正在使用psycopg2作为我正在使用的樱桃应用程序和cli& phpgadmin手动处理一些操作。这是python代码:

#One connection per thread
cherrypy.thread_data.pgconn = psycopg2.connect("...") 
...
#Later, an object is created by a thread :
class dbobj(object):
 def __init__(self):
  self.connection=cherrypy.thread_data.pgconn
  self.curs=self.connection.cursor(cursor_factory=psycopg2.extras.DictCursor)
...
#Then,
try:
 blabla
 self.curs.execute(...)
 self.connection.commit()
except:
 self.connection.rollback()
 lalala
...
#Finally, the destructor is called :
def __del__(self):
 self.curs.close()

我遇到了psycopg或postgres的问题(尽管我认为后者更有可能)。在发出一些问题后,我的连接就丢失了。同样,phpgadmin -usually-也会被删除;在多次提出请求后,它会提示我重新连接。只有CLI保持持久性。

问题是,这些都是随机发生的,我甚至无法追查原因。我可以在几页请求后被锁定,或者在请求数百页之后从未真正遇到过任何问题。在终止应用程序后,我在postgres日志中发现的唯一错误是:

...
LOG:  unexpected EOF on client connection
LOG:  could not send data to client: Broken pipe
LOG:  unexpected EOF on client connection
...

我想在每次创建新的dbobj实例时创建一个新连接,但我绝对不想这样做。

另外,我已经读过,除非提交所有事务,否则可能会遇到类似的问题:我对每个INSERT / UPDATE查询都使用try / except块,但是我从来没有将它用于SELECT查询,也不想使用它写更多的样板代码(顺便说一句,他们需要提交吗?)。即使是这样,为什么phpgadmin会关闭?

<。> .conf文件中的max_connections设置为100,所以我认为这也不是原因。一个樱桃工人只有10个线程。

有没有人知道我应该先看哪儿?

3 个答案:

答案 0 :(得分:1)

Psycopg2需要在每次事务(包括SELECT查询)之后提交或回滚,或者它会离开连接&#34; IDLE IN TRANSACTION&#34;。现在这是文档中的警告:

警告:默认情况下,任何查询执行,包括一个简单的SELECT都将启动一个事务:对于长时间运行的程序,如果不采取进一步的操作,会话将保持“在事务中空闲”,这是一个不合需要的条件,原因有几个(会话持有锁,表膨胀......)。对于长期存在的脚本,要么确保尽快终止事务,要么使用自动提交连接。

答案 1 :(得分:0)

要确切了解您填充和访问cherrypy.thread_data的位置有点困难。我建议调查psycopg2.pool.ThreadedConnectionPool,而不是试图自己将一个conn绑定到每个线程。

答案 2 :(得分:0)

即使我不知道为什么成功的SELECT查询会阻止连接,但几乎每个不需要与另一个查询一起工作的查询都会解决问题后,.commit()会出现问题