求助关于Django连接MySQL中断的问题

173 views
Skip to first unread message

Alvin Qi

unread,
Feb 26, 2018, 1:17:59 AM2/26/18
to python-cn(华蟒用户组,CPyUG 邮件列表)
我没曾想到Django的ORM是这样麻烦……(还是我的打开方式不对=_=

这个问题其实挺常见,就是Django应用在执行查询请求的过程中报错:

  File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 122, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 381, in get
    num = len(clone)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 240, in __len__
    self._fetch_all()
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 52, in __iter__
    results = compiler.execute_sql()
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 846, in execute_sql
    cursor = self.connection.cursor()
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/base.py", line 233, in cursor
    cursor = self.make_cursor(self._cursor())
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/base.py", line 204, in _cursor
    self.ensure_connection()
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/base.py", line 199, in ensure_connection
    self.connect()
  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/base.py", line 199, in ensure_connection
    self.connect()
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/base.py", line 171, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/base.py", line 264, in get_new_connection
    conn = Database.connect(**conn_params)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/__init__.py", line 81, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 221, in __init__
    self.set_character_set(charset)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 312, in set_character_set
    super(Connection, self).set_character_set(charset)
OperationalError: (2013, 'Lost connection to MySQL server during query')

从网上查到的信息判断,这个应该是因为MySQL Server将连接挂起(halt),Client(也就是Django程序)的连接还是活跃状态,直接执行查询,就会报出这个错误。

所以呢,我将MySQL的wait_timeout调整为86400(24小时),将connect_timeout设置为300,同时Django里MASTER_DATABASE_CONN_MAX_AGE值为60。
理论上,这样的客户端发起的每一条链接,都会在MySQL Server连接活跃时间范围内,应该是没问题的。

但还是不行,问题依旧。
所以是我遗漏了什么东西么?是不是有其他的配置/方法需要考虑?
还是说我的思路就错了,一直忽视了什么关键的东西?

附上运行环境:
  • Ubuntu 12.04.5
  • Django 1.9.3
  • mysqlclient-1.3.12
  • MySQL 5.6
感谢社区里各位老师的指导和帮助:)

Zoom.Quiet

unread,
Feb 26, 2018, 1:26:42 AM2/26/18
to CPyUG~华蠎用户组
连接池?
> --
> 邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
> 规则: http://code.google.com/p/cpyug/wiki/PythonCn
> 详情: http://code.google.com/p/cpyug/wiki/CpyUg
> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
> ---
> 您收到此邮件是因为您订阅了Google网上论坛上的“python-cn(华蟒用户组,CPyUG 邮件列表)”群组。
> 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+...@googlegroups.com
> 要发帖到此群组,请发送电子邮件至pyth...@googlegroups.com
> 要查看更多选项,请访问https://groups.google.com/d/optout



--
life is pathetic, go Pythonic! 人生苦短, Python当歌!
俺: http://zoomquiet.io
授: http://creativecommons.org/licenses/by-sa/2.5/cn/
怒: 冗余不做,日子甭过!备份不做,十恶不赦!
KM keep growing environment culture which promoting organization learning!

Alvin Qi

unread,
Feb 26, 2018, 1:32:31 AM2/26/18
to pyth...@googlegroups.com
Django 1.9哪有连接池……
Django 1.9并没有连接池,这个可以说很糟糕了

> 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
> 要发帖到此群组,请发送电子邮件至python-cn@googlegroups.com
> 要查看更多选项,请访问https://groups.google.com/d/optout



--
life is pathetic, go Pythonic! 人生苦短, Python当歌!
俺: http://zoomquiet.io
授: http://creativecommons.org/licenses/by-sa/2.5/cn/
怒: 冗余不做,日子甭过!备份不做,十恶不赦!
KM keep growing environment culture which promoting organization learning!
--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了 Google 网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。
要退订此主题,请访问https://groups.google.com/d/topic/python-cn/mysEDjqJM88/unsubscribe
要退订此群组及其所有主题,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
要向此群组发帖,请发送电子邮件至 pyth...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/d/optout



--
Alvin Qi

Alvin Qi

unread,
Feb 26, 2018, 1:34:40 AM2/26/18
to pyth...@googlegroups.com
嗯...

或者说,您有推荐的做连接池的Python包么?我在网上搜到了一些,都没什么人用,根本不敢用。

在 2018年2月26日 下午2:26,Zoom.Quiet <zoom....@gmail.com>写道:
> 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
> 要发帖到此群组,请发送电子邮件至python-cn@googlegroups.com
> 要查看更多选项,请访问https://groups.google.com/d/optout



--
life is pathetic, go Pythonic! 人生苦短, Python当歌!
俺: http://zoomquiet.io
授: http://creativecommons.org/licenses/by-sa/2.5/cn/
怒: 冗余不做,日子甭过!备份不做,十恶不赦!
KM keep growing environment culture which promoting organization learning!
--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了 Google 网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。
要退订此主题,请访问https://groups.google.com/d/topic/python-cn/mysEDjqJM88/unsubscribe
要退订此群组及其所有主题,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
要向此群组发帖,请发送电子邮件至 pyth...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/d/optout



--
Alvin Qi

胡阳

unread,
Feb 26, 2018, 1:49:39 AM2/26/18
to pyth...@googlegroups.com
Django的CONN_MAX_AGE的逻辑是保存连接在线程里。

我知道的有两种可能会导致你配置了CONN_MAX_AGE,还会引起连接数增多的情况:
1. 开启了DEBUG模式
2. 用gevent来跑Django
>> > 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+...@googlegroups.com
>> > 要发帖到此群组,请发送电子邮件至pyth...@googlegroups.com
>> > 要查看更多选项,请访问https://groups.google.com/d/optout
>>
>>
>>
>> --
>> life is pathetic, go Pythonic! 人生苦短, Python当歌!
>> 俺: http://zoomquiet.io
>> 授: http://creativecommons.org/licenses/by-sa/2.5/cn/
>> 怒: 冗余不做,日子甭过!备份不做,十恶不赦!
>> KM keep growing environment culture which promoting organization learning!
>>
>> --
>> 邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
>> 规则: http://code.google.com/p/cpyug/wiki/PythonCn
>> 详情: http://code.google.com/p/cpyug/wiki/CpyUg
>> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
>> ---
>> 您收到此邮件是因为您订阅了 Google 网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。
>>
>> 要退订此主题,请访问https://groups.google.com/d/topic/python-cn/mysEDjqJM88/unsubscribe
>> 要退订此群组及其所有主题,请发送电子邮件到python-cn+...@googlegroups.com
>> 要向此群组发帖,请发送电子邮件至 pyth...@googlegroups.com
>> 要查看更多选项,请访问 https://groups.google.com/d/optout
>
>
>
>
> --
> Alvin Qi
>
> --
> 邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
> 规则: http://code.google.com/p/cpyug/wiki/PythonCn
> 详情: http://code.google.com/p/cpyug/wiki/CpyUg
> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
> ---
> 您收到此邮件是因为您订阅了Google网上论坛上的“python-cn(华蟒用户组,CPyUG 邮件列表)”群组。
> 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+...@googlegroups.com
> 要发帖到此群组,请发送电子邮件至pyth...@googlegroups.com
> 要查看更多选项,请访问https://groups.google.com/d/optout



--
人生苦短,还是用python好。

博客地址: http://www.the5fire.com

by 胡阳

Alvin Qi

unread,
Feb 26, 2018, 2:04:28 AM2/26/18
to pyth...@googlegroups.com
实际上是用uWSGI来跑的,并且没有开启Debug模式。
开启CONN_MAX_AGE的原因是为了持久化(复用)数据库连接(毕竟Django 1.9里没有连接池机制,我也确实不敢乱用网上的包),否则根据之前的配置,数据库连接会暴涨。

现在uWSGI的配置:
[uwsgi]
socket = :1201
pythonpath = /some/where/path
module = wsgi
chdir = /some/path
plugins = python
buffer-size = 65535
master = true
processes = 4
threads = 2

这样是不是就应该去掉CONN_MAX_AGE参数呢?



>> > 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
>> > 要发帖到此群组,请发送电子邮件至python-cn@googlegroups.com

>> > 要查看更多选项,请访问https://groups.google.com/d/optout
>>
>>
>>
>> --
>> life is pathetic, go Pythonic! 人生苦短, Python当歌!
>> 俺: http://zoomquiet.io
>> 授: http://creativecommons.org/licenses/by-sa/2.5/cn/
>> 怒: 冗余不做,日子甭过!备份不做,十恶不赦!
>> KM keep growing environment culture which promoting organization learning!
>>
>> --
>> 邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
>> 规则: http://code.google.com/p/cpyug/wiki/PythonCn
>> 详情: http://code.google.com/p/cpyug/wiki/CpyUg
>> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
>> ---
>> 您收到此邮件是因为您订阅了 Google 网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。
>>
>> 要退订此主题,请访问https://groups.google.com/d/topic/python-cn/mysEDjqJM88/unsubscribe
>> 要退订此群组及其所有主题,请发送电子邮件到python-cn+unsubscribe@googlegroups.com

>> 要向此群组发帖,请发送电子邮件至 pyth...@googlegroups.com
>> 要查看更多选项,请访问 https://groups.google.com/d/optout
>
>
>
>
> --
> Alvin Qi
>
> --
> 邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
> 规则: http://code.google.com/p/cpyug/wiki/PythonCn
> 详情: http://code.google.com/p/cpyug/wiki/CpyUg
> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
> ---
> 您收到此邮件是因为您订阅了Google网上论坛上的“python-cn(华蟒用户组,CPyUG 邮件列表)”群组。
> 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
> 要发帖到此群组,请发送电子邮件至python-cn@googlegroups.com
> 要查看更多选项,请访问https://groups.google.com/d/optout



--
人生苦短,还是用python好。

博客地址: http://www.the5fire.com

by 胡阳
--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了 Google 网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。
要退订此主题,请访问https://groups.google.com/d/topic/python-cn/mysEDjqJM88/unsubscribe
要退订此群组及其所有主题,请发送电子邮件到python-cn+unsubscribe@googlegroups.com

要向此群组发帖,请发送电子邮件至 pyth...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/d/optout



--
Alvin Qi

Living42

unread,
Feb 26, 2018, 10:35:33 AM2/26/18
to python-cn(华蟒用户组,CPyUG 邮件列表)
traceback 上看起来是在建立一个新的数据连接时抛出的,所以你改 connect_timeout wait_timeout CONN_MAX_AGE 都没作用。

在 2018年2月26日星期一 UTC+8下午2:17:59,Alvin Qi写道:

佟铁

unread,
Feb 26, 2018, 9:44:27 PM2/26/18
to python-cn(华蟒用户组,CPyUG 邮件列表)
1. 就我的编程经验看,不常见。
2. 之前遇到过一次,是因为写入mysql的内容过大,导致mysql丢失连接,后来使用mongo解决。建议排查下数据大小。

悔恨的阿毛

unread,
Feb 27, 2018, 9:33:35 PM2/27/18
to python-cn(华蟒用户组,CPyUG 邮件列表)
之前遇到过的两种情况:
1. MySQL连接闲置太久,导致这次连接的时候Client认为还在连接,MySQL服务端已经断掉了连接
解决方法可以是多一个try-catch,或者在这种操作之前ensure connection

2. 数据过大,请检查MySQL的配置,MySQL的配置可能导致拒绝耗时过长或者数据过大的请求。


在 2018年2月26日星期一 UTC+8下午2:17:59,Alvin Qi写道:
我没曾想到Django的ORM是这样麻烦……(还是我的打开方式不对=_=
Reply all
Reply to author
Forward
0 new messages