导读
作者:魏新平
知数堂第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对连接的闲置时间没有用处
扫码加入QQ技术交流群
MySQL 8.0|MGR研究院-ZST
(QQ群号:650149401)