MySQL中有许多关于timeout 参数,你都能清楚他们的含义吗?
看其名字大概也能知道其含义,若能说的非常清楚,却不尽然。特别是interactive_timeout和wait_timeout,非常令人困惑。网上查了许多解说,也都讲得不够透彻。我也下一番功夫,深入解说下这两个变量。
官方定义
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(). See also wait_timeout.
- 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_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()). See also interactive_timeout.
在解释上,这两个参数相互引用了对方,说明他们的关系非常密切。其实wait_timeout的解释说明了一切: 关闭一个非交互连接前的等待时间。一个会话建立时,session级别的wait_timeout参数会根据全局变量interactive_timeout 或 wait_timeout 初始化。具体选取哪个变量则看客户端的连接是交互式连接还是非交互式连接。(注意这里冒出了一个新概念:交互式连接。后面再讲)其实对于会话来讲,只有wait_timeout是起作用的。会话级别的interactive_timeout是不起作用的。session中的wait_timeout在建立连接时会根据连接类型初始化为全局变量中interactive_timeout或wait_timeout的值。这一点讲清楚,我们再说交互式连接。
交互式连接文档中也说了一点,就是mysql_real_connect()函数调用时使用了CLIENT_INTERACTIVE参数。一般看到这里就蒙了。我门再进一步看这个函数的原形
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
这个函数是存在于mysql客户端中,是mysql于数据库建立连接时调用的。前面几个参数都好看懂,注意最后一个client_flag。官方解释有一大堆:
The value of client_flag is usually 0, but can be set to a combination of the following flags to enable certain features:
这个参数有很多可选,这里不再粘贴,相见后面参考资料,其中又一个是:
CLIENT_INTERACTIVE: Permit interactive_timeout seconds of inactivity (rather than wait_timeout seconds) before closing the connection. The client’s session wait_timeout variable is set to the value of the session interactive_timeout variable.
也就是说客户端在连接mysql服务器时使用了这个flag,那么这个连接就是交互式连接。使用mysql命令连接默认是交互式连接.
我们再看服务器端源码实现(auth/sql_authentication.cc):
由此我们可以看到,如果判断连接启用了CLIENT_INTERACTIVE,就把session级别的interactive_timeout,赋值给session级别的wait_timeout.而session级别的interactive_timeout是用Global级别interactive_timeout继承来的。官方描述有些不是很清楚,通过上面的几段英文我们也看到了一些矛盾的地方。但可以确定的只有session级别的wait_timeout在起作用,session 级别的interactive_timeout不控制任何行为。
测试
设置wait_timeout 为5s , 等待5s再发送命令。
发现连接被重联。
设置interactive_timeout=5s, 等待5s,再发送命令
发现连接不变,interactive_timeout的值依然是5.
- 设置全局interactive_timeout=5,重新连接。
- 发现wait_timeout的值为5, 5s后连接被重连
- 而global wait_timeout依然是28800。
影响
一般不确定连接是交互式还是非交互式的情况下,可这两个变量设置为相同的值,官方给这两个变量的默认值也是相同的。
此参数对应用的影响,就是但一个连接闲置时长达到其session级别的wait_timeout时,服务器端会关闭连接,如果应用端使用连接池依然使用这个连接发送请求时,会报Lost connection to server during query错误,或者Last packet sent to the server was 12 ms ago类似错误。因此应用端连接配置应启用自动重连。各种语言的连接器应该都有相应参数。
而对mysql server的影响是,当它们的值设置较小时会及时关闭非活动sleep连接,节省连接资源,以免连接达到最大连接数而无法响应请求。如果经常卡到大量长时间sleep连接,可通过缩小这个两个变量的值,以节省连接资源。
登录 | 立即注册