Psycopg / Postgres: подключения зависают случайным образом - PullRequest
2 голосов
/ 13 ноября 2010

Я использую psycopg2 для приложения cherrypy, над которым я сейчас работаю, и 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, как правило, также удаляется; он побуждает меня восстановить соединение после нескольких запросов. Только CLI остается постоянным.

Проблема в том, что это происходит очень случайно, и я даже не могу выяснить, в чем причина. Я могу либо получить блокировку после нескольких запросов страниц, либо никогда не сталкиваться с чем-либо после запроса сотен страниц. Единственная ошибка, которую я обнаружил в журнале postgres после завершения работы приложения:

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

Я думал о создании нового соединения каждый раз, когда создается новый экземпляр dbobj, но я абсолютно не хочу этого делать.

Кроме того, я читал, что можно столкнуться с подобными проблемами, если не все транзакции зафиксированы: я использую блок try / исключением для каждого отдельного запроса INSERT / UPDATE, но я никогда не использую его для запросов SELECT и не хочу написать еще больше стандартного кода (кстати, они должны быть зафиксированы?). Даже если это так, почему phpgadmin закрывается?

max_connections установлено в 100 в файле .conf, поэтому я не думаю, что это тоже причина. Один вишневый рабочий имеет только 10 нитей.

У кого-нибудь есть идеи, куда мне в первую очередь смотреть?

Ответы [ 3 ]

1 голос
/ 20 октября 2016

Psycopg2 требует фиксации или отката после каждой транзакции, включая запросы SELECT, или он оставляет соединения «IDLE IN TRANSACTION».Теперь это предупреждение в документах:

Предупреждение: по умолчанию любое выполнение запроса, в том числе простой SELECT, запускает транзакцию: для долго выполняющихся программ, если никаких дальнейших действий не предпринимается, сеанс останется.«Бездействие в транзакции», нежелательное условие по нескольким причинам (блокировки удерживаются сеансом, таблицы раздуваются ...).Для долгоживущих сценариев убедитесь, что транзакция завершена как можно скорее, или используйте соединение автоматической фиксации.
0 голосов
/ 17 ноября 2010

Несмотря на то, что я понятия не имею, почему успешные SELECT запросы блокируют соединение, выливается .commit() после того, как почти каждый запрос, который не должен работать в сочетании с другим, решил проблему.

0 голосов
/ 14 ноября 2010

Немного трудно понять, где именно вы заполняете и получаете доступ к cherrypy.thread_data. Я бы порекомендовал исследовать psycopg2.pool.ThreadedConnectionPool вместо того, чтобы пытаться привязать один коннект к каждому потоку самостоятельно.

...