【发布时间】:2014-03-18 03:31:24
【问题描述】:
我有一个 Python 程序,它在后台运行数周,并且每隔一段时间进行一次数据库查询。为此,我正在使用 ORM peewee(版本 2.2.1)。我使用MySQL 作为后端。
最近我在访问数据库时遇到了一个反复出现的问题,通常是在运行程序几天之后。 peewee 引发的错误是
peewee.OperationalError: (2006, 'MySQL server has gone away')
回溯在peewee 深处。我把它贴在这里,但由于我的virtualenv 使文件名太长,我正在缩短它们:
File ".../local/lib/python2.7/site-packages/peewee.py", line 2910, in save
ret_pk = self.insert(**field_dict).execute()
File ".../local/lib/python2.7/site-packages/peewee.py", line 2068, in execute
return self.database.last_insert_id(self._execute(), self.model_class)
File ".../local/lib/python2.7/site-packages/peewee.py", line 1698, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File ".../local/lib/python2.7/site-packages/peewee.py", line 2232, in execute_sql
self.commit()
File ".../local/lib/python2.7/site-packages/peewee.py", line 2104, in __exit__
reraise(new_type, new_type(*exc_value.args), traceback)
File ".../local/lib/python2.7/site-packages/peewee.py", line 2223, in execute_sql
res = cursor.execute(sql, params or ())
File ".../local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File ".../local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
peewee.OperationalError: (2006, 'MySQL server has gone away')
我发现的可能的解决方案尝试:
- 在this question 中,其中一位cmets 建议每隔一段时间对
MySQL服务器进行一次ping 操作,以使其(连接?)保持活动状态。不过,我不确定如何通过 ORM 做到这一点。 (我应该每小时简单地SELECT 1吗?) - 在 4 个月前打开的 this github peewee issue 中,提到了相同的错误,但声称已解决(而且我使用的是更新版本)。
- 在
trac的7 year old issue 中,一个建议是将MySQL的超时时间延长3 天。 - 在此forum discussion 中,建议选择增加
MySQL的超时时间,但提供了“使用 MySQL JDBC 连接器的 autoReconnect 选项”的替代方案。我试图弄清楚 Python 的MySQLdb模块是否存在这样的选项,但找不到。 - 我在重新连接行为上找到了这个MySQL reference page,但是对于我对
MySQL的理解来说有点复杂(通常我只使用ORM),我不知道如何从@987654341 应用它@。
即使我能够 ping 数据库以使连接保持更长时间的活动,我认为在不需要连接时保持连接活动被认为是一种不好的做法。有没有办法通过 ORM 重新打开连接?我认为 ping 和增加 MySQL 的超时作为解决方法,而真正的解决方案是在需要时重新连接(真正的解决方案是我所要求的)。
【问题讨论】:
-
查看MySQL中
wait_timeout的值 -
我猜是8小时;这不是默认的吗?
-
连接完成后只需手动调用
db.close()。 -
我从来没有“完成”它;该程序只是继续运行。尽管如此,如果我不使用连接,我认为保持连接不是一个好习惯。我设置的任何超时都可能不够大。
标签: python mysql orm mysql-python peewee