1.说明

在使用Django接入celery耗时异步任务之后发现会报错OperationalError(2006, 'MySQL server has gone away'),这个报错是指MySQL断开了,具体原因得实际分析

2.解决

MySQL两个相关设置

2.1.等待超时时间

MySQL有一个默认等待时间,超过这个时间没有活动则自动断开连接。默认是28800秒,即8小时

# 登录MySQL之后查看wait_timeout的值
show global variables like '%timeout';
# 如果wait_timeout太小,可以适当改大点,例如24小时
set global wait_timeout=60*60*24;

注意上面的方法只是临时修改,重启后失效,若要永久修改,需修改配置文件

vim /etc/mysql/mysql.conf.d/mysqld.cnf

在配置文件里加上如下配置项

wait_timeout = 36000
interactive_timeout = 36000 # 一般需要这个一起修改

改完之后进行保存,然后重启MySQL才会生效

2.2.数据量太大

如果查询的数据量太大可能会导致数据库断开

# 查看最大允许数据量
show global variables like 'max_allowed_packet';
# 如果max_allowed_packet太小,可以适当改大点,例如50M
set global max_allowed_packet=1024*1024*50;

注意上面的方法只是临时修改,重启后失效,若要永久修改,需修改配置文件

2.3.关闭所以数据库连接

如果上面的方法都不管用,可以每次使用cursor之前都确保之前的数据库连接已经关闭

for conn in connections.all():
    conn.close_if_unusable_or_obsolete()
with connection.cursor() as cursor:
    cursor.execute("sql")

上面的方法是关闭所有无用数据库,另外还可以关闭当前数据库

from django.db import connection

connection.close()
OperateJournal.objects.create(xxx=xxx)
3.其他类似错误

另外还遇到了django.db.utils.InterfaceError: (0, '') 这个错误,它也是因为MySQL等待时间过长而自动断开连接了,所以可以再次使用ORM之前先关闭之前的全部连接

from django.db import connections

connections.close_all()
nodes = Node.objects.filter(is_active=True).all()
...

由于没有给出具体报错信息,所以也不确定是否超过了最大连接数,可以试一下修改MySQL的最大连接数

查看最大连接数

show variables like "%max_connections%";

临时修改(重启MySQL之后会失效)

set GLOBAL max_connections=1000;

永久修改,即修改配置文件,例如vim /etc/mysql/mysql.conf.d/mysqld.cnf,加上如下配置项,之后记得保存和重启MySQL才能生效

max_connections = 100
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐