2013-08-06 2 views
4

используя pymysql connect to mysql, оставьте программу в течение длительного времени, например, покиньте офис ночью и вернитесь на следующее утро. В течение этого периода никаких действий в этом приложении не было. теперь выполнение фиксации базы данных даст эту ошибку.pymysql потерял соединение через длительный период

File "/usr/local/lib/python3.3/site-packages/pymysql/cursors.py", line 117, in execute 
    self.errorhandler(self, exc, value) 
    File "/usr/local/lib/python3.3/site-packages/pymysql/connections.py", line 189, in defaulterrorhandler 
    raise errorclass(errorvalue) 

pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query') 

перезапустить веб-сервер (торнадо), это нормально.Почему, если оставить это долгое время, получите эту ошибку?

+3

Возможно, вы нажмете [wait_timeout] (http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout) своего сервера mysql – Gryphius

+0

Возможный дубликат [ Потерянное соединение с сервером MySQL во время запроса] (http://stackoverflow.com/questions/1884859/lost-connection-to-mysql-server-during-query) – msw

+0

кажется, что это проблема wait_timeout, поскольку ошибка появилась только во время действительно долгое время, как решить эту проблему? Я не думаю, что увеличить это хороший вариант. – user2003548

ответ

4

wait_timeout существует по какой-либо причине: длительные незанятые соединения расточительно ограничены ресурсами сервера. Вы правы: это не правильный подход.

К счастью, это Python, который имеет надежный механизм исключения. Я не знаком с pymysql но предположительно у вас есть «open_connection» метод где-то, что позволяет

try: 
    cursor.do_something() 
except pymysql.err.OperationalError as e: 
    if e[0] == 2013: # Lost connection to server 
     # redo open_connection and do_something 
    else: 
     raise 

Поскольку вы не размещать код вызова, я не могу структурировать этот пример, чтобы соответствовать приложениям. Там стоит отметить оговорку except: во-первых, они всегда должны быть как можно более узкими, в этом случае есть (предположительно) множество OperationalErrors, и вы знаете только, как бороться с «Потерянным соединением».

В случае, если это не исключение, связанное с потерей связи, вы должны повторно поднять его, чтобы он не проглотил. Если вы не знаете, как обращаться с другими OperationalErrors, это будет передано в стек и приведет к информативному сообщению об ошибке, которое разумно делать, поскольку ваш курсор, вероятно, бесполезен в любом случае к тому времени.

Перезапуск веб-сервера устраняет потерянное соединение как случайный побочный эффект повторной инициализации всего; обработка исключения в коде - гораздо более мягкий способ достижения вашей цели.

+1

интерфейс связи имеет функцию ping, может использовать ping (reconnect = True), чтобы решить эту проблему, благодаря вашему правильному правилу – user2003548