【问题标题】:Django - OperationalError: (2006, 'MySQL server has gone away')Django - OperationalError: (2006, 'MySQL server has gone away')
【发布时间】:2011-12-11 17:24:55
【问题描述】:

底线第一:如何在 django 中刷新 MySQL 连接?

在出现MySQL server has gone away 错误后,我发现MySQL documentation 和其他来源(here)建议增加wait_timeout MySQL 参数。对我来说,这似乎是一种解决方法而不是解决方案。我宁愿保留一个合理的wait_timeout,并在代码中刷新连接。

错误:

  File "C:\my_proj\db_conduit.py", line 147, in load_some_model
    SomeModel.objects.update()
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\models\manager.py", line 177, in update
    return self.get_query_set().update(*args, **kwargs)
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\models\query.py", line 469, in update
    transaction.commit(using=self.db)
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\transaction.py", line 142, in commit
    connection.commit()
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\backends\__init__.py", line 201, in commit
    self._commit()
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\backends\__init__.py", line 46, in _commit
    return self.connection.commit()
OperationalError: (2006, 'MySQL server has gone away')

设置:Django 1.3.0,MySQL 5.5.14,innodb 1.1.8,Python 2.6.6,Win7 64bit

【问题讨论】:

    标签: mysql django


    【解决方案1】:

    有同样的问题。 我需要知道如何在 django 中检查 MySQLdb 连接的连接状态。 我想这可以通过

    来实现
    try:
        cursor.execute(sql)
    catch OperationalError:
        reconnect
    

    有人有更好的主意吗?

    更新

    我的决定

    self.connection.stat()
    if self.connection.errno()!=0:
    

    如果错误重新创建连接,请检查 mysqldb 连接的状态

    再次更新

    如果连接关闭,您还需要服务案例

    if self.connection.open:
        self.connection.stat()
    

    刷新连接只是重新创建它

        db_settings = settings.DATABASES['mysql_db']
        try:
            self.connection = MySQLdb.connect(host=db_settings['HOST'],port=int(db_settings['PORT']),db=db_settings['NAME'],user=db_settings['USER'],passwd=db_settings['PASSWORD'])
        except MySQLdb.OperationalError, e:
            self.connection = None
    

    【讨论】:

    • 如何重新建立连接?
    【解决方案2】:

    解决思路很明确:如果当前连接断开,重新连接mysql。

    请查看:

    def make_sure_mysql_usable():
        from django.db import connection, connections
        # mysql is lazily connected to in django.
        # connection.connection is None means
        # you have not connected to mysql before
        if connection.connection and not connection.is_usable():
            # destroy the default mysql connection
            # after this line, when you use ORM methods
            # django will reconnect to the default mysql
            del connections._connections.default
    

    【讨论】:

    • 这应该是公认的答案。删除连接对象将导致它在下次运行 Django 查询时重新创建,因此在查询之前运行此函数应确保刷新连接。此外,如果您想使用字符串名称删除数据库(如果您配置了多个数据库),您可以使用“del connections._connections.__dict__['default']”。
    【解决方案3】:

    从 Django 1.6 开始,您可以使用

    import django.db
    
    django.db.close_old_connections()
    

    这与 adamsmith 的回答基本相同,只是它处理多个数据库并且还支持 CONN_MAX_AGE 设置。 Django 在每个请求之前和之后自动调用close_old_connections(),因此您通常不必担心它,除非您在正常的请求/响应周期之外有一些长时间运行的代码。

    【讨论】:

      【解决方案4】:

      导致此异常的主要原因主要是由于客户端理想比mysql服务器上的wait_timeout长。

      为了防止这种错误,django 支持一个名为CONN_MAX_AGE 的选项,如果旧连接理想时间过长,django 可以重新创建新连接。 所以你应该确保CONN_MAX_AGE 值小于wait_timout 值。

      重要的一点是,djangowsgi 通过调用 close_old_connections 处理检查 CONN_MAX_AGE 的每个请求。所以你主要不需要关心这个。但是,如果您在标准的单独应用程序中使用django,则没有触发器来运行该功能。所以你必须手动调用它。所以让我们在你的代码库中调用close_old_connections

      注意:close_old_connections 将保留未过期的旧连接。在高频查询的情况下,您的连接仍然会被重用。

      【讨论】:

        【解决方案5】:

        这种方式也可以关闭空闲的连接,让事情变好。

        所以在很长一段时间后需要进行查询之前,运行以下几行即可:

        from django.db import close_old_connections
        
        # To prevent the error if possible.
        close_old_connections()
        # Then the following sentence should be always ok.
        YourModel.objects.all()
        

        【讨论】:

          猜你喜欢
          • 2012-12-19
          • 2013-12-16
          • 2015-10-20
          • 2011-02-04
          • 2015-07-22
          • 2012-10-30
          • 2019-10-13
          • 2015-12-02
          • 2017-12-21
          相关资源
          最近更新 更多