扭曲的adbapi cp_reconnect无法正常工作

时间:2012-10-01 16:26:15

标签: python mysql twisted

我有一个与MySQL数据库对话的旋风网络服务。如果暂时没有活动(我猜的时间超过8小时),我会在重新启动Web服务时收到以下错误:

  

_mysql_exceptions.OperationalError:(2006,'MySQL服务器已经消失')

我见过this post regarding cp_reconnect,我在创建连接池时实现了这个:

pool = adbapi.ConnectionPool("MySQLdb", host=self.host, user=self.user,
    passwd=self.password, db=self.database, cursorclass=MySQLdb.cursors.DictCursor,
    cp_reconnect=True)

我原本以为这会修复它,似乎有一段时间了,但是现在我看到服务器上没有活动一段时间后“MySQL服务器已经消失”错误了。 / p>

我已阅读this MySQL documentation regarding wait_timeout,我可以通过这种方式修复它,但为什么cp_reconnect功能对我不起作用?我正在解释adbapi文档意味着如果您指定cp_reconnect参数,那adbadpi将处理MySQL发送的错误并为您重新尝试查询。所以基本上你不必直接在代码中处理错误。我误解了吗?

3 个答案:

答案 0 :(得分:5)

几年前我一直在寻找解决方案。我在网上某处找到的解决方案是子类化ConnectionPool并覆盖_runInteraction,您强制重新连接特定的错误代码。 快速谷歌搜索引导我访问此网站:http://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/并附带代码。 我没有必要考虑再次关闭MySQL连接。

答案 1 :(得分:3)

在对扭曲的邮件列表进行一些讨论并查看扭曲的bug跟踪器之后,结果发现这是一个尚未修复的已知错误。

以下是mailing list discussion的链接。

以下是twisted bug tracker issue的链接。

可能的解决方案:

  1. 增加服务器上的wait_timeout值。
  2. 覆盖ConnectionPool类中的方法referenced above
  3. 在每个连接中设置定期“ping”以使其保持活动状态。
  4. 自己修复adbapi中的错误。
  5. 其中,我可能会选择#1。

答案 2 :(得分:2)

链接http://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/不再起作用,甚至不是Web Archive版本。这里摘录了Twistar 1.3,它引用了相同的解决方案:

https://pypi.python.org/pypi/twistar

class ReconnectingMySQLConnectionPool(adbapi.ConnectionPool):
    """
    This connection pool will reconnect if the server goes away.  This idea was taken from:
    http://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/
    """
    def _runInteraction(self, interaction, *args, **kw):
        try:
            return adbapi.ConnectionPool._runInteraction(self, interaction, *args, **kw)
        except MySQLdb.OperationalError, e:
            if e[0] not in (2006, 2013):
                raise
            log.err("Lost connection to MySQL, retrying operation.  If no errors follow, retry was successful.")
            conn = self.connections.get(self.threadID())
            self.disconnect(conn)
            return adbapi.ConnectionPool._runInteraction(self, interaction, *args, **kw)