Django (2006, 'MySQL server has gone away') 本地重现与解决
最近我们的Django项目供Java Sofa应用进行tr调用时, 经常会出现一个异常: django.db.utils.OperationalError: (2006, 'MySQL server has gone away')
. 本文记录了分析, 本地重现与解决此问题的全过程.
原因分析:
Django在1.6引入长链接(Persistent connections)的概念, 可以在一个HTTP请求中一直用同一个连接对数据库进行读写操作.
但我们的应用对数据库的操作太不频繁了, 两次操作数据库的间隔大于MySQL配置的超时时间(默认为8个小时), 导致下一次操作数据库时的connection过期失效.
Our databases have a 300-second (5-minute) timeout on inactive connections. That means, if you open a connection to the database, and then you don’t do anything with it for 5 minutes, then the server will disconnect, and the next time you try to execute a query, it will fail.
重现问题:
设置mysql wait_timeout
为10s
在macOS上的mysql配置文件路径: /usr/local/etc/my.cnf
1 |
# Default Homebrew MySQL server config |
重启mysql:
1 |
➜ ~ brew services restart mysql |
检查wait_timeout
的值是否已被更新.
1 |
mysql> show variables like '%wait_timeout%'; |
重现exception:
1 |
>>> XXX.objects.exists() |
有意思的一个点是, sleep 10s 之后, 第一次操作数据库, 会出现(2013, 'Lost connection to MySQL server during query’)
异常. 之后再操作数据库, 才会抛出(2006, 'MySQL server has gone away’)
异常.
解决问题:
第一个最暴力的方法就是增加mysql的wait_timeout
让mysql不要太快放弃连接. 感觉不太靠谱, 因为不能杜绝这种Exception的发生.
第二个办法就是手动把connection直接关闭:
1 |
>>> Alarm.objects.exists() |
发现不会出现(2006, 'MySQL server has gone away’)
异常了, 但总感觉还是不够优雅.
最终决定在客户端(Django), 设置超时时间(CONN_MAX_AGE: 5
)比mysql服务端(wait_timeout = 10
)小:
1 |
DATABASES = { |
但很奇怪没有生效??? 看了源代码, 发现只有在request_started
(HTTP request)和request_finished
的时候, 在close_if_unusable_or_obsolete
才用到CONN_MAX_AGE
并去验证时间关闭connection.
具体代码见: python3.6/site-packages/django/db/__init__.py#64
1 |
# Register an event to reset transaction state and close connections past |
而我的代码是处理一个任务而不是HTTP请求, 所以不会触发这个signal. 于是我写了一个装饰器, 在任务的开始和结束的时候, 关闭所有数据库连接.
1 |
from django.db import connections # ref: django.db.close_old_connections |
ps. CONN_MAX_AGE默认其实为0, 意味着默认在http请求和结束时会关闭所有数据库连接.
其他:
django.db中connection和connections的区别???
connection
对应的是默认数据库的连接, 用代码表示就是connections[DEFAULT_DB_ALIAS]
connections
对应的是setting.DATABASES中所有数据库的connection
Django (2006, 'MySQL server has gone away') 本地重现与解决的更多相关文章
- [django1.6]跑批任务错误(2006, 'MySQL server has gone away')
有个django的定时任务的需求,调用django的orm来对数据库进行数据处理. 在交互环境下直接启动pyhton脚本没有问题,放在定时任务中时候,总是出现 (2006, 'MySQL serve ...
- flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)
这篇主要介绍在这次项目中使用的peewee 文档地址:http://peewee.readthedocs.org/en/latest/index.html 首先我们要初始化一个数据库连接对象.这里我使 ...
- MySQL(Navicat)运行.sql文件时报错:[Err] 2006 - MySQL server has gone away 的解决方法
背景: 今天导入一个数据量很大的.sql文件时,报错: 原因: 可能是sql语句过长,超过mysql通信缓存区最大长度. 解决:1. 编辑 MySQL 安装目录下的 my.ini,在最后添加以下内容: ...
- MySQL导入sql脚本错误:2006 - MySQL server has gone away
到如一些小脚本很少报错,但最近导入一个10+M的SQL脚本,却重复报错: Error occured at:2014-03-24 11:42:24 Line no.:85 Error Code: 20 ...
- 【mysql】之MySQL导入sql脚本错误:2006 - MySQL server has gone away
到如一些小脚本很少报错,但最近导入一个10+M的SQL脚本,却重复报错: Error occured at:2014-03-24 11:42:24Line no.:85Error Code: 2006 ...
- #2006 - MySQL server has gone away 问题解决方法 (全) (转)
#2006 - MySQL server has gone away 问题解决方法 原文地址:http://www.cnblogs.com/bisonjob/archive/2009/08/18/15 ...
- MYSQL导入数据报错|MYSQL导入超大文件报错|MYSQL导入大数据库报错:2006 - MySQL server has gone away
导SQL数据库结构+数据时,如果数据是批量插入的话会报错:2006 - MySQL server has gone away. 解决办法:找到你的mysql目录下的my.ini配置文件(如果安装目录没 ...
- Yii2 解决2006 MySQL server has gone away问题
Yii2 解决2006 MySQL server has gone away问题 Yii2版本 2.0.15.1 php后台任务经常包含多段sql,如果php脚本执行时间较长,或者sql执行时间较长, ...
- SQLyog恢复数据库报错解决方法【Error Code: 2006 - MySQL server has gone away】
https://blog.csdn.net/niqinwen/article/details/8693044 导入数据库的时候 SQLyog 报错了 Error Code: 2006 – MySQL ...
随机推荐
- JFinal学习 & Gradle配置续 & Tomcat配置
接上一篇对Gradle的学习,再用JFinal项目再建一个. 参考了这篇文章:https://my.oschina.net/u/1010578/blog/390094 但是其中没有代码,所以看了这篇 ...
- [反汇编练习] 160个CrackMe之036
[反汇编练习] 160个CrackMe之036. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...
- android wifi state and wifi ap state
/** * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if * ...
- LattePanda 之深入学习 Firmata通讯
前言 原创文章,转载引用务必注明链接,水平有限,如有疏漏,欢迎指正. 本文使用Markdown写成,为获得更好的阅读体验和正常的链接.图片显示,请访问我的博客原文: http://www.cnblog ...
- es6 对象浅拷贝的2种方法
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- nagios插件之登陆SBC监控电话数
运行:sbc_calls_status_new auto_ssh_sbc_10_17.sh | auto_ssh_sbc_11_17.sh vi sbc_calls_status_new.c #inc ...
- java开始到熟悉103-104
本次内容:linkedlist() 此次是承接上次arraylist(),自己实现linkedlist()(内容较少) package list; /** * 自定义linkedlist类 * @au ...
- VS中 build,rebuild,clean
一般来说Rebuild=99%*(Clean+Build),效果在非常小的可能性下会不同,一般可以忽略. Rebuild是对Solution下的所有项目,逐个进行 Clean+Build.不论文件更改 ...
- SubmittingPatches, SubmitChecklist and CodingStyle
How to Get Your Change Into the Linux Kernel or Care And Operation Of Your Linus Torvalds For a pers ...
- Springmvc返回信息乱码解决
恩...基本上所有的配置信息都弄上了,但是还是乱码,最后在方法上面添加了下面的参数,就完美解决了: @RequestMapping(value="/action.action",m ...