2010-11-13 53 views
2

我正在使用psycopg2作为我正在处理的cherrypy应用程序,并且clog & phpgadmin可以手动处理某些操作。这里的Python代码:Psycopg/Postgres:连接随机挂出

#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的一个问题(altough我认为后者的可能性更大)。在发送了几个查询后,我的连接就完蛋了。同样,phpgadmin - 通常也会被丢弃;它提示我在多次提出请求后重新连接。只有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会关闭?

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

有没有人有一个想法,我应该先看看?

回答

0

尽管我不知道为什么成功的SELECT查询会阻止连接,但在几乎每一个不需要与另一个查询结合使用的查询都能解决问题之后,溢出.commit()

0

确切地看到你在哪里填充和访问cherrypy.thread_data有点困难。我建议您调查psycopg2.pool.ThreadedConnectionPool,而不是试图将一个conn绑定到每个线程。

1

Psycopg2在每个事务(包括SELECT查询)后都需要提交或回滚,或者它将连接保留为“IDLE IN TRANSACTION”。这在文档中现在是一个警告:

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