MySQL 的连接时长控制--interactive_timeout和wait_timeout
在用MySQL客户端对数据库进行操作时,如果一段时间没有操作,再次操作时,常常会报如下错误:
ERROR 2013 (HY000): Lost connection to MySQL server during query
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
这个报错信息就意味着当前的连接已经断开,需要重新建立连接。
那么,连接建立后,连接的时长是如何确定的呢?
在MySQL中,这个与两个参数interactive_timeout
和wait_timeout
的设置有关。
注:以下说明基于MySQL 5.7.
1.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.
interactive_timeout参数,定义了对于交互式连接,服务端等待数据的最大时间。如果超过这个时间,服务端仍然没有收到数据,则会关闭连接。
所谓交互式client,是指调用mysql_real_connect()函数建立连接时,设置了CLIENT_INTERACTIVE选项。比较常用的就是命令行终端。
查看interactive_timeout的值:
mysql> show global variables like 'interactive_timeout%';
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
+---------------------+-------+
1 row in set (0.01 sec)
默认是28800,单位秒,即8个小时
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参数,定义对于非交互式连接,服务端等待数据的最长时间。如果超过这个时间,服务端仍然没有收到数据,则会关闭连接。
在连接线程启动的时候,根据连接的类型,决定会话级的wait_timeout的值是初始化为全局的wait_timeout,还是全局的interactive_timeout。即如果是交互式连接,会话变量wait_timeout初始化为全局的interactive_timeout,否则,初始化为全局的wait_timeout。
查看wait_timeout的值:
mysql> show global variables like 'wait_timeout%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
1 row in set (0.00 sec)
默认同样是28800s,即8小时。
根据上述定义,两者的区别显而易见:interactive_timeout针对交互式连接,wait_timeout针对非交互式连接。所谓的交互式连接,即在mysql_real_connect()函数中使用了CLIENT_INTERACTIVE选项。
说得直白一点,通过mysql命令行终端连接数据库是交互式连接,通过jdbc等连接数据库是非交互式连接。
下面来测试一下,确认如下问题:
- 控制连接最大空闲时长的是哪个参数。
- 会话变量wait_timeout的继承问题
2.控制连接最大空闲时长的是哪个参数
先给出答案:wait_timeout
接下来进行验证。
2.1 只修改会话的wait_timeout参数
查看当前会话的wait_timeout和interactive_timeout。
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.00 sec)
设置当前会话的wait_timeout为10s
mysql> set session wait_timeout=10;
Query OK, 0 rows affected (0.00 sec)
再次查看
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 10 |
+---------------------+-------+
2 rows in set (0.00 sec)
等待10s,再次查看
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 8
Current database: *** NONE ***
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.01 sec)
可以看到,等待10s后再执行操作,原来的连接已经断开,并重新建立连接。
2.2 只修改会话的interactive_timeout参数
首先查看当前会话的interactive_timeout和wait_timeout.
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.00 sec)
接着,设置当前会话的interactive_timeout为10s
mysql> set session interactive_timeout=10;
Query OK, 0 rows affected (0.00 sec)
再次查看
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 10 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.01 sec)
等待10s,再次查看
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 10 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.00 sec)
可以看到,即使等待10后,连接是正常的。所以,设置interactive_timeout,对连接的时长没有影响。
3.会话变量wait_timeout的继承问题
上面已经提到,如果是交互式连接,则继承自全局变量interactive_timeout的值,如果是非交互式连接,则继承自全局变量wait_timeout的值。
下面进行验证。
3.1 只修改全局变量interactive_timeout的值
首先查看全局的interactive_timeout和wait_timeout。
mysql> show global variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.00 sec)
接着,设置全局的interactive_timeout为10s。
mysql> set global INTERACTIVE_TIMEOUT=10;
Query OK, 0 rows affected (0.00 sec)
再次查看
mysql> show global variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 10 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.00 sec)
开启另外一个MySQL客户端,查看会话变量的值:
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 10 |
| wait_timeout | 10 |
+---------------------+-------+
2 rows in set (0.01 sec)
发现,WAIT_TIMEOUT的值已经变为10了。
等待10s后,再次查看,会发现原来的连接已经断开,连接的时长设置已经生效。
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 70
Current database: *** NONE ***
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 10 |
| wait_timeout | 10 |
+---------------------+-------+
2 rows in set (0.01 sec)
但通过非终端测试,wait_timeout的值依旧是28800:
package main
import (
"database/sql"
"log"
_ "github.com/go-sql-driver/mysql"
)
var DB *sql.DB
var dataBase = "root:Aa123456@tcp(127.0.0.1:3306)/?loc=Local&parseTime=true"
func mysqlInit() {
var err error
DB, err = sql.Open("mysql", dataBase)
if err != nil {
log.Fatalln("open db fail:", err)
}
DB.SetMaxOpenConns(1)
err = DB.Ping()
if err != nil {
log.Fatalln("ping db fail:", err)
}
}
func main() {
mysqlInit()
execSql()
}
func execSql() {
var variableName string
var value int
sql := "show session variables where Variable_name in ('interactive_timeout', 'wait_timeout')"
rows, err := DB.Query(sql)
if err != nil {
log.Println("query failed:", err)
return
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&variableName, &value)
if err != nil {
log.Println("rows.Scan failed:", err)
return
}
log.Println("variable_name:", variableName, ", value:", value)
}
}
output:
2019/10/13 17:11:22 variable_name: interactive_timeout , value: 10
2019/10/13 17:11:22 variable_name: wait_timeout , value: 28800
结果输出如下
INTERACTIVE_TIMEOUT: 10
WAIT_TIMEOUT: 28800
3.2 只修改全局变量wait_timeout的值
首先查看全局的interactive_timeout和wait_timeout。
mysql> show global variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.00 sec)
接着,将全局的WAIT_TIMEOUT设置为20s。
mysql> set global WAIT_TIMEOUT=20;
Query OK, 0 rows affected (0.07 sec)
再次查看
mysql> show global variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 20 |
+---------------------+-------+
2 rows in set (0.00 sec)
开启另外一个mysql客户端,查看会话变量的值
mysql> show session variables where Variable_name in ('interactive_timeout', 'wait_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+---------------------+-------+
2 rows in set (0.00 sec)
WAIT_TIMEOUT的值依旧是28800.
查看非终端的代码执行的结果:
func execSql() {
var variableName string
var value int
sql := "show session variables where Variable_name in ('interactive_timeout', 'wait_timeout')"
rows, err := DB.Query(sql)
if err != nil {
log.Println("query failed:", err)
return
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&variableName, &value)
if err != nil {
log.Println("rows.Scan failed:", err)
return
}
log.Println("variable_name:", variableName, ", value:", value)
}
}
output:
2019/10/13 17:23:10 variable_name: interactive_timeout , value: 28800
2019/10/13 17:23:10 variable_name: wait_timeout , value: 20
修改程序,执行sql语句后,等待25s后,再次执行sql语句,查看执行情况。
func main() {
mysqlInit()
for {
execSql()
time.Sleep(25*time.Second)
}
}
func execSql() {
var variableName string
var value int
sql := "show session variables where Variable_name in ('interactive_timeout', 'wait_timeout')"
rows, err := DB.Query(sql)
if err != nil {
log.Println("query failed:", err)
return
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&variableName, &value)
if err != nil {
log.Println("rows.Scan failed:", err)
return
}
log.Println("variable_name:", variableName, ", value:", value)
}
}
output:
2019/10/13 17:26:46 variable_name: interactive_timeout , value: 28800
2019/10/13 17:26:46 variable_name: wait_timeout , value: 20
[mysql] 2019/10/13 17:27:11 packets.go:36: unexpected EOF
[mysql] 2019/10/13 17:27:11 packets.go:141: write tcp 127.0.0.1:53878->127.0.0.1:3306: write: broken pipe
2019/10/13 17:27:11 variable_name: interactive_timeout , value: 28800
2019/10/13 17:27:11 variable_name: wait_timeout , value: 20
可以看到,等待25s后,再次执行sql,此时连接已经断开。
底层又重新建立连接。
4.总结
控制连接最大空闲时长的wait_timeout参数。
关于wait_timeout的继承
- 对于非交互式连接,类似于jdbc连接,wait_timeout的值继承自全局变量wait_timeout。
- 对于交互式连接,类似于mysql命令行终端,wait_timeout的值继承全局变量interactive_timeout。
判断一个连接的空闲时间,可通过show processlist输出中Sleep状态的时间
mysql> show processlist;
+----+------+----------------------+------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+----------------------+------+---------+------+-------+------------------+
| 2 | root | localhost | NULL | Query | 0 | init | show processlist |
| 6 | repl | 192.132.2.66:56001 | NULL | Sleep | 1201 | | NULL |
+----+------+----------------------+------+---------+------+-------+------------------+
2 rows in set (0.03 sec)
5.参考
https://www.cnblogs.com/ivictor/p/5979731.html
http://www.cnblogs.com/cenalulu/archive/2012/06/20/2554863.html
http://www.cnblogs.com/Alight/p/4118515.html
MySQL 的连接时长控制--interactive_timeout和wait_timeout的更多相关文章
- MySQL左连接时 返回的记录条数 比 左边表 数量多
在学MySQL的连接时,为了便于记忆,就将左连接 记做 最后结果的总记录数 和 进行左连接的左表的记录数相同,简单的说就是下面这个公式 count(table A left join table B) ...
- MySQL 8 连接时出现 1251 和 2059 错误
MySQL 8 连接时出现 1251 和 2059 错误 原因是MySQL 8 改了密码加密算法.1 原来是:mysql_native_password MySQL8 改成了 caching_sha2 ...
- 修改MYSQL的默认连接时长
show global variables like 'wait_timeout'; 设置成10小时; set global wait_timeout=36000;
- JAVA Socket 连接时长
其实关于这个问题可能用到的人不会很多,不过我在这里还是说说. 正常很多人写socket通信时,都会直接通过new socket(IP,PORT)直接去链接服务器.其实这种做法也没有错误,但是若当服务器 ...
- MySQL JOIN 连接时,条件为以逗号分隔的字段与 ID 相匹配
一.背景 有一张相片表,一张相片所属标签表,一张相片可以归属于多个标签,表结构如下: 现在需要通过一次查询,得到每一张照片对应的标签名称,标签名称之间以固定的分隔符连接,结果如下图: 二.查询语句 原 ...
- mysql jdbc连接时的小问题java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
这次重新修改老程序时出现了上面的错误,排查过后最终找到问题所在:root帐户默认不开放远程访问权限,所以需要修改一下相关权限. 打开MySQL目录下的my.ini文件(win10默认安装在C:\Pro ...
- centos下MySQL Workbench连接时崩溃的解决方法
在centos6.5中使用MySQL Workbench 6.3.8链接数据库崩溃,如果是在终端使用命令“mysql-workbench”打开的话会有如下错误提示: /usr/libexec/mysq ...
- MySQL 线程池&连接池&长连接&短连接
线程池 简介 1.mysql每连接每线程,mysql都分配一个单独的线程,该线程处理客户端发来的所有命令 2.每个线程会占用一定的系统资源,线程数越多消耗的系统资源也越多 3.线程的创建和销毁有一定的 ...
- Mysql:mysql5.7长时间不连接失效问题
问题 mysql5数据库连接超时问题:待机一晚上后,第二天早上第一次登录总是失败. 查看日志发现如下错误: "com.mysql.jdbc.exceptions.jdbc4.Communic ...
随机推荐
- configure.ac:91: error: possibly undefined macro: AC_SEARCH_LIBS
debian系统上,手动编译tmux的时候,执行./autogen.sh出现如下报错: $ ./autogen.sh configure.ac:: error: possibly undefined ...
- react 预览pdf 转换
function getReader(response){ return new Promise(function(resolve,reject){ response.blob().then( blo ...
- 打印n对括号的全部有效组合(左右括号正确匹配)Java实现
一.问题导出 今天在做算法题目的时候遇到了一道左右括号匹配的问题,问题如下: 二.问题思考 (1)这种要列出全部可能性的题目很容易想到由小到大去发现规律,用递归或者暴力搜索. 首先1的情况,一个括号只 ...
- Man手册--nmap
目录 nmap使用手册 附录: nmap使用手册 附录: NMAP(1) Nmap Reference Guide NMAP(1) NAME nmap - Network exploration to ...
- Hadoop_33_Hadoop HA的搭建
Hadoop HA的搭建,可参考链接:https://blog.csdn.net/mrbcy/article/details/64939623 说明: 1.在hadoop2.0中通常由两个Nam ...
- [Abp vNext微服务实践] - 前后端分类
一.前景 abp vNext是ABP 开源 Web应用程序框架,是abp的新一代开源web框架.框架完美的集成.net core.identity server4等开源框架,适用于构建web应用程序和 ...
- Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/usr/local/bin/tensorboard'
使用pip install --user tensorflow-serving-api命令即可
- ubuntu 16.04中文输入法安装
转自: http://blog.csdn.net/u011795345/article/details/53041707 最近刚给笔记本装了Ubuntu+win10双系统,但是ubuntu16.04没 ...
- 长春理工大学第十四届程序设计竞赛F Successione di Fixoracci——找规律&&水题
题目 链接 题意:给出x数列的定义: $T_0 = a$ $T_1 = b$ $T_n = T_{n-2} \bigoplus T_{n-1} $ 求第 $n$ 项( $0 \leqslant a,b ...
- Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) E. Vasya and Good Sequences(DP)
题目链接:http://codeforces.com/contest/1058/problem/E 题意:给出 n 个数,对于一个选定的区间,区间内的数可以通过重新排列二进制数的位置得到一个新的数,问 ...