Django升级后:MySQL服务器已经消失

Se *_*orm 19 mysql django timeout

我最近从Django 1.4升级到Django 1.7,因为我不断收到一些脚本的错误信息,有时:

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

脚本很长或连续运行的任务可能涉及几分钟内不与数据库通信的阶段,因此连接超时.但是,在升级之前,这没有问题,因为Django似乎会自动重新建立连接.现在它并不意味着任务经常在中间停止和失败.

有谁知道改变了什么以及如何解决它?

它可能与该票证/修复有关:https://code.djangoproject.com/ticket/21463

非常感谢!

Eug*_*tov 31

这种行为的原因是持久连接数据库,这是在Django 1.6中引入的.

为了防止连接超时错误,你应该设置CONN_MAX_AGEsettings.py以值小于wait_timeout在MySQL配置(my.cnf).在这种情况下,Django检测到连接需要在MySQL抛出之前重新打开.MySQL 5.7的默认值是28800秒.

settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'CONN_MAX_AGE': 3600,
        <other params here>
    }
}
Run Code Online (Sandbox Code Playgroud)

文档:https://docs.djangoproject.com/en/1.7/ref/settings/#conn-max-age

my.cnf:

wait_timeout = 28800
Run Code Online (Sandbox Code Playgroud)

文档:https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_wait_timeout

  • 事实上,这并没有解决我的问题。仅在使用 uwsgi 和 nginx 时发生。我怀疑这更多地与此有关:https://serverfault.com/questions/407612/error-2006-mysql-server-has-gone-away (2认同)

ta2*_*2-1 18

我有一个正在运行的后台进程rqworker,它执行单独的作业以在一些用户操作后刷新一些数据.

OperationalError: (2006, 'MySQL server has gone away') 如果在超过wait_timeout几秒钟内没有用户操作,我总是得到.即使我将CONN_MAX_AGE设置为小于MySQL wait_timeout.

据我了解,如果Django通过此超时自动检查并关闭其连接,则更改CONN_MAX_AGE可能会有所帮助.但是Django 1.7.x仅在每个请求之前和之后检查它(参见django/db/init .py#L101-L112).

Django ticket 15119中所述,我们可以看到Django正在进行ping以在执行每个查询之前验证连接是否处于活动状态.在提交282b2f4中修复此问题.

Django开发人员为https://code.djangoproject.com/ticket/21597#comment:29中的所有问题提供了一个简短的答案.

因此,我的rqworker流程必须为每个新作业验证连接本身.(注意:如果我们关闭连接,那么Django将创建一个新连接).

我将根据请求的方法使用Django进行工作,django.db.close_old_connections()并在每个工作之前和之后调用.是的,CONN_MAX_AGE应该小于MySQL wait_timeout,因为Django不检查是否MySQL server has gone awaydjango.db.close_old_connections()方法中.


Dee*_*eep 9

在Django 1.9上:我有一个持续的Django Shell在unix屏幕上运行,无人看管超过48小时.当我回到它并跑了<some_model>.objects.filter它扔了 OperationalError: (2006, 'MySQL server has gone away')

快速import django.db; django.db.close_old_connections()为我做了诀窍.

我找不到close_old_connections()关于Django Docs for 1.9的文档但是这里是它在Github上的Django Codebase中实现直接链接


小智 5

在django 1.6中,当wait_timeout传递(mysql)时,然后DB访问导致(2006,'MySQL服务器已经消失')错误.django 1.5.1中的情况并非如此

当使用运行django代码的工作者(使用gearman)时,我注意到了这个错误.

重现:

通过编辑/etc/mysql/my.cnf将超时设置为低值在[mysqld]下添加以下内容

wait_timeout = 10
interactive_timeout = 10
Run Code Online (Sandbox Code Playgroud)

然后

%python manage.py shell

>>> # access DB 
>>> import django.contrib.auth.models
>>> print list(django.contrib.auth.models.User.objects.all())
>>> import time
>>> time.sleep(15)
>>> print list(django.contrib.auth.models.User.objects.all())
Run Code Online (Sandbox Code Playgroud)

现在你得到了错误.

我在网上找到的简单解决方案是在访问之前调用django.db.close_connection()

>>> import django.db
>>> django.db.close_connection()
>>> print list(django.contrib.auth.models.User.objects.all())
Run Code Online (Sandbox Code Playgroud)

工作正常.