4

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

_mysql_exceptions.OperationalError: (2006, 'MySQL server has gone away')

我看过这篇关于 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 服务器已消失”错误。

我已经阅读了有关 wait_timeout 的 MySQL 文档,我可以按照我想的方式修复它,但是为什么 cp_reconnect 功能对我不起作用?我将 adbapi 文档解释为如果您指定 cp_reconnect 参数,adbadpi 将处理 MySQL 发送的错误并为您重新尝试查询。所以基本上你不必直接在你的代码中处理错误。我误解了吗?

4

3 回答 3

5

几年前我一直在寻找解决方案。我在网上某处找到并解决的解决方案是 subclassingConnectionPool和 overriding _runInteraction,您可以在其中强制重新连接特定的错误代码。一个快速的谷歌搜索将我带到这个网站:http ://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/包含代码。我再也不用考虑死掉 MySQL 连接了。

于 2012-10-02T08:00:55.343 回答
3

在对扭曲的邮件列表进行了一些讨论并查看了扭曲的错误跟踪器之后,事实证明这是一个尚未修复的已知错误。

这是邮件列表讨论的链接。

这是扭曲的错误跟踪器问题的链接。

可能的解决方案:

  1. 增加服务器上的 wait_timeout 值。
  2. 覆盖上面引用的 ConnectionPool 类中的方法。
  3. 在每个连接中设置一个定期“ping”以使其保持活动状态。
  4. 自己修复 adbapi 中的 bug。

其中,我可能会选择#1。

于 2012-10-05T16:54:47.840 回答
2

链接http://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/不再起作用,甚至 Web 存档版本也不起作用。这里是 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)
于 2016-02-03T13:46:19.073 回答