MySQL中的“Too many connections”的原因
in python with 0 comment

MySQL中的“Too many connections”的原因

in python with 0 comment

问题分析

首先,我认为存在即为合理。这种提示并非说是MySQL的问题,而是我们程序的问题。
我举一个简单的例子,在很多爬虫项目中,我曾尝试使用PyMySQL来创建MySQL连接来进行相关的数据库操作。这样看着似乎没有什么问题,但当使用多线程以后,会发现原本创建的连接无法使用。这是因为:在PEP249中,相关线程安全的描述如下:

threadsafetyMeaning
0Threads may not share the module.
1Threads may share the module, but not connections.
2Threads may share the module and connections.
3Threads may share the module, connections and cursors.

我们可以得知,在标志为1时,线程之间可以共享模块,但无法共享连接。也就意味着我们的每一个线程连接数据库时,都需要创建相应的连接。

但这样就结束了么?

import pymysql.cursors

config = {
    'host': '127.0.0.1',
    'port': 3306,
    'user': 'root',
    'password': 'root',
    'db': 'test',
    'charset': 'utf8',
}

while True:
    connection = pymysql.connect(**config)
    # do something
    connection.close()

貌似这么写是结束了,但是不久就会出现我们题目中所提到的问题->Too many connections.

这是为什么?

对,我也有怀疑,为什么我分明关闭了连接(connection.close()),为什么还会出现这种错误?
这个问题的答案就是,程序关闭了连接,而服务端并没有关闭。
怎么证明?

# 使用root登陆MySQL
show global variables like 'wait_timeout';

# 得到如下的信息
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.00 sec)

这便就是MySQL的默认的超时时间,即8个小时(单位是秒)。在查询结束后,将连接置于sleep状态,即使不存在网络等其他因素的问题,也不能允许客户端长久的建立连接,即超过8小时候,MySQL服务端主动关闭连接。
官方描述:

wait_timeout:The number of seconds the server waits for activity on a noninteractive connection before closing it. On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeoutvalue, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()).

科学合理的解决

我想,这就是使用ORM的一个原因了。

Comments are closed.