作者:魏新平

知数堂第5期MySQL实战班学员,第10期MySQL优化班学员,现任职助教。

当我们用MySQL客户端或者程序(如Java,Python等)连接MySQL后,如果闲置一段时间(就是不执行任何SQL),再次执行SQL的时候就会报失去连接的错误,如:

ERROR 2006 (HY000): MySQL server has gone away

Lost connection to MySQL server during query

这是MySQL控制连接数的机制,会自动把一些闲置时间超过配置值的连接kill掉。

闲置时间配置参数

这里涉及的参数有两个,wait_timeout 和 interactive_timeout。而MySQL的参数又分为GLOBAL级别和SESSION级别,所以严格的讲,会涉及到四个参数。

参数的官方解释:

interactive_timeout: The number of seconds the server waits for activity on an interactive connection before closing it. An interactive client is defined as a client that uses the CLIENT_INTERACTIVE option to mysql_real_connect().

翻译:interactive_timeout控制交互式连接的空闲时间,如果调用mysql的mysql_real_connect()函数的时候,使用了CLIENT_INTERACTIVE参数,该连接就定义为交互式连接。

wait_timeout: The number of seconds the server waits for activity on a noninteractive connection before closing it.

翻译:wait_timeout控制非交互连接的闲置时间。

On thread startup, the session waittimeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()). See also interactive_timeout.

翻译:在连接建立的时候,session级别的wait_timeout会根据连接的分类来选择是继承global级别的interactive_timeout的值和global级别的wait_timeout的值。

看完官方针对interactive_timeout和wait_timeout的解释,其实会发现写的挺让人难以理解的,没有讲清楚SESSION级别和GLOBAL级别的两个参数是如何控制连接的闲置时间的,而且很难区分什么是交互式连接,什么是非互式连接,只能从源代码层面去区分。

接下来我们平常使用的连接方式来做实验(使用的MySQL版本为Percona的MySQL5.7)。

先分别设置GLOBAL级别的interactive_timeout和wait_timeout。

1、重新用MySQL客户端开一个窗口,查看SESSION参数

可以看出SESSION级别的wait_timeout和interactive_timeout都继承了GLOBAL.interactive_timeout的值,也就是说mysql客户端属于交互式连接。

2、用PyMySQL查看参数值(Python3版本)

{'@@GLOBAL.interactive_timeout': 20, '@@GLOBAL.wait_timeout': 40, '@@session.interactive_timeout': 20, '@@session.wait_timeout': 40}

结论:SESSION级别的wait_timeout和interactive_timeout继承了各自的GLOBAL级别的值,也就是说Python的Pymysql连接被定义为非交互式连接。

1、MySQL官方客户端

然后用同样的方式去测试剩下的三个参数,发现只有修改SESSION级别的wait_timeout才会有

ERROR 2006 (HY000): MySQL server has gone away

错误(请务必在同一个会话当中测试)。

2、Pymysql(Python3)

用另外3个参数来运行上述代码,只有修改session级别wait_timeout才会出现如下错误:

pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')

结论:从实验二可以看出,针对已经存在的连接来说,交互式和非交互式连接的闲置时间都是由SESSION级别的wait_timeout控制的。

1、交互式连接和非交互式连接的空闲时间都是由SESSION级别的wait_timeout时间控制的

2、SESSION级别的wait_timeout值是再连接初始化的时候,根据连接的分类来确定是从GLOBAL 级别的interactive_timeout值继承还是GLOBAL级别的wait_timeout值继承

3、SESSION级别的interactive_timeout对连接的闲置时间没有用处

加入知数堂

挑战40万+年薪!

叶金荣与吴炳锡联合打造

领跑IT精英培训

行业资深专家强强联合,倾心定制

MySQL实战/MySQL优化/MongoDB/

Python/ SQL优化/Hadoop+ELK

数门精品课程

“阅读原文”可获更多正课试听视频

密码:hg3h

紧随技术发展趋势,定期优化培训教案

融入大量生产案例,贴合企业一线需求

社群陪伴学习,一次报名,可学1年

DBA、开发工程师必修课

上千位学员已华丽转身,薪资翻番,职位提升

改变已悄然发生,你还在等什么?

MySQL 8.0|MGR研究院-ZST