Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL timeout调研与实测

MySQL timeout调研与实测

作者头像
九州暮云
发布于 2019-08-21 02:58:09
发布于 2019-08-21 02:58:09
1.1K00
代码可运行
举报
文章被收录于专栏:九州牧云九州牧云
运行总次数:0
代码可运行

说明:

接触网络编程我们不得不提的就是超时,TCP建立连接的超时,数据报文发送/接收超时等等,mysql在超时上也做足了功夫。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Variable_name Default Value
connect_timeout 5
interactive_timeout 28800
net_read_timeout 30
net_write_timeout 60
wait_timeout 28800

上面这5个超时是本次调研的重点,当然MySQL绝对不指这5种超时的配置,由于经历和时间有限,本次只谈这5种。

一、 connect_timeout

这个比较好理解,字面上看意思是连接超时。”The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake”。 MySQL连接一次连接需求经过6次“握手”方可成功,任意一次“握手”失败都有可能导致连接失败,如下图所示。

前三次握手可以简单理解为TCP建立连接所必须的三次握手,MySQL无法控制,更多的受制于不TCP协议的不同实现,后面的三次握手过程超时与connect_timeout有关。简单的测试方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$time telnet mysql_ip_addr port
$ time telnet 127.0.0.1 5051
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
?
Connection closed by foreign
host.
real    0m5.005s #这里的5秒即mysql默认的连接超时
user    0m0.000s
sys     0m0.000s

Telnet未退出前通过show processlist查看各线程状态可见,当前该连接处于授权认证阶段,此时的用户为“unauthenticated user”。细心的你懂得,千万不要干坏事。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+--+--------------------+---------------+----+-------+----+----------------+----------------+
|Id|User                |Host           |db  |Command|Time|State           |Info            |
+--+--------------------+---------------+----+-------+----+----------------+----------------+
| 6|root                |localhost      |NULL|Query  |   0|NULL            |show processlist|
| 7|unauthenticated user|localhost:58598|NULL|Connect|NULL|Reading from net|NULL            |
+--+--------------------+---------------+----+-------+----+----------------+----------------+

二、 wait_timeout

等待超时,那mysql等什么呢?确切的说是mysql在等用户的请求(query),如果发现一个线程已经sleep的时间超过wait_timeout了那么这个线程将被清理掉,无论是交换模式或者是非交换模式都以此值为准。

注意:wait_timeout是session级别的变量哦,至于session和global变量的区别是什么我不说您也知道。手册上不是明明说wait_timeout为not interactive模式下的超时么?为什么你说无论是交换模式或者非交换模式都以此值为准呢?简单的测试例子如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show variables like "%timeout%";
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 5     | 
| delayed_insert_timeout     | 300   | 
| innodb_lock_wait_timeout   | 50    | 
| innodb_rollback_on_timeout | OFF   | 
| interactive_timeout        | 28800 | 
| net_read_timeout           | 30    | 
| net_write_timeout          | 60    | 
| slave_net_timeout          | 3600  | 
| table_lock_wait_timeout    | 50    | 
| wait_timeout               | 28800 | 
+----------------------------+-------+
10 rows in set (0.00 sec)
 
Date : 2012-2-24 Fri 22:41:24
#可见我把interactive_timeout改为1秒后经过了4秒的时间没有任何请求,连接却没有被断开。为了验证wait_timeout我再把interactive_timeout改回来
mysql> set interactive_timeout=28800;
Query OK, 0 rows affected (0.00 sec)
Date : 2012-2-24 Fri 22:43:43

mysql> show variables like "%timeout%";
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 5     | 
| delayed_insert_timeout     | 300   | 
| innodb_lock_wait_timeout   | 50    | 
| innodb_rollback_on_timeout | OFF   | 
| interactive_timeout        | 28800 | 
| net_read_timeout           | 30    | 
| net_write_timeout          | 60    | 
| slave_net_timeout          | 3600  | 
| table_lock_wait_timeout    | 50    | 
| wait_timeout               | 28800 | 
+----------------------------+-------+
10 rows in set (0.00 sec)
Date : 2012-2-24 Fri 22:43:46
 
mysql> set wait_timeout=1;
Query OK, 0 rows affected (0.00 sec)
 
Date : 2012-2-24 Fri 22:43:52
 
mysql> set wait_timeout=1;
ERROR 2006 (HY000): MySQL server has gone away  
No connection. Trying to reconnect...
Connection id:    8
Current database: *** NONE ***
 
Query OK, 0 rows affected (0.00 sec)
 
Date : 2012-2-24 Fri 22:43:55 #可见即使在交互模式下真正起作用的也是wait_timeout而不是interactive_timeout

那为什么手册上说在交互模式下使用的是interactive_timeout呢,原因如下:

check_connection函数在建立连接初期,如果为交互模式则将interactive_timeout值赋给wait_timeout,骗您误以为交互模式下等待超时为interactive_timeout 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (thd->client_capabilities & CLIENT_INTERACTIVE)
     thd->variables.net_wait_timeout=thd->variables.net_interactive_timeout;

三、 interactive_timeout

参数含义:服务器关闭交互式连接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。

参数默认值:28800秒(8小时)

四、 net_write_timeoutite_timeout

看到这儿如果您看累了,那下面您得提提神了,接下来的两个参数才是我们遇到的最大的难题。 “The number of seconds to wait for a block to be written to a connection before aborting the write.” 等待将一个block发送给客户端的超时,一般在网络条件比较差的时,或者客户端处理每个block耗时比较长时,由于net_write_timeout导致的连接中断很容易发生。下面是一个模拟的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql > set global max_allow_packet=1;
#目的是让结果集被分成多个包传输给客户端 
mysql > set global net_write_timeout=1; 
#include 
#include 
#include 
main() {
   MYSQL *conn;
   MYSQL_RES *res;
   MYSQL_ROW row;
   char *server = "localhost";
   char *user = "test"; 
   char *password = ""; /* set me first */
   char *database = "test";
   conn = mysql_init(NULL);
   /* Connect to database */
   if (!mysql_real_connect(conn, server, 
         user, password, database, 0, NULL, 0)) {
      fprintf(stderr, "%s\n", mysql_error(conn));
      exit(1);
   }
   /* send SQL query */
   if (mysql_query(conn, "SELECT * from big_table;")) {
      fprintf(stderr, "%s\n", mysql_error(conn));
      exit(1);
   }
   res = mysql_use_result(conn);
#mysql_use_result不会一次将全部结果给都丢给客户端内存
   /* output table name */
   printf("MySQL Tables in mysql database:\n");
   sleep(7); #模拟网络环境不稳定或客户端处理耗时
   while ((row = mysql_fetch_row(res)) != NULL){
      printf("%s \n", row[0]);
   }
   /* close connection */
   mysql_free_result(res);
   mysql_close(conn);
}

四、 net_read_timeout

“The number of seconds to wait fprintfor more data from a connection before aborting the read.”。Mysql读数据的时的等待超时,可能的原因可能为网络异常或客户端or服务器端忙无法及时发送或接收处理包。这里我用的是iptables来模拟网络异常,生成一个较大的数据以便于给我充足的时间在load data的过程中去配置iptables规则。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql > set global max_allowed_packet=1073741824;
mysql > set global net_read_timeout=1;
mysql > create table test.test(a char(10)) engine=myisam;
for((i=0;i<100000;i++));do echo "abcdefghij" >> data.txt;done

mysql -uroot -h 127.0.0.1 -P 3306 --local-enable=1
--max-allowed-packet=1073741824
mysql > load data local infile 'load.txt' into table test;
 
iptables -F
/sbin/iptables -A INPUT -p tcp --dport 3306 -j DROP
/sbin/iptables -A OUTPUT -p tcp --sport 3306 -j DROP
iptables -L

执行完iptables命令后show processlist可以看到load data的连接已经被中断掉了,但因为这里我选择了myisam表,所以select count(*) from test;可以看到数据还是被插入了一部分。

五、 net_retry_count

“超时”的孪生兄弟“重试”,时间原因这个我没有进行实际的测试,手册如是说,估且先信它一回。

If a read or write on a communication port is interrupted, retry this many times before giving up. This value should be set quite high on FreeBSD because internal interrupts are sent to all threads. On Linux, the “NO_ALARM” build flag (-DNO_ALARM) modifies how the binary treats both net_read_timeout and net_write_timeout. With this flag enabled, neither timer cancels the current statement until after the failing connection has been waited on an additional net_retry_count times. This means that the effective timeout value becomes” (timeout setting) × (net_retry_count+1)”.

FreeBSD中有效,Linux中只有在build的时候指定NO_ALARM参数时net_retry_count才会起作用。 说明:目前线上使用的版本都未指定NO_ALARM。

参考链接:

MySQL中的配置参数interactive_timeout和wait_timeout(可能导致过多sleep进程的两个参数)

官方文档关于interactive_timeout的解释

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL占用CPU过高 查找原因及解决 多种方式
-- select * from information_schema.PROCESSLIST where info is not null;
用户5005176
2021/08/08
7.8K0
OperationalError: (2006, 'MySQL server has gone away')
OperationalError (2006, ‘MySQL server has gone away’)
周小董
2019/03/25
2.6K0
那些年踩过的MySQL wait_timeout参数的坑
MySQL wait_timeout参数修改问题,可能经常会有DBA遇到过,下面就试验一下并看看会有什么现象。
俊才
2019/08/08
2.8K0
那些年踩过的MySQL wait_timeout参数的坑
通过案例分析MySQL中令人头疼的Aborted告警
这篇文章通过案例跟大家分析了MySQL中令人头疼的Aborted告警的相关资料,文中将Aborted告警介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
拓荒者
2019/03/11
8620
MySQL优化之缓存优化
MySQL的优化指的是一个很大的系统,面试的时候我之前是从sql的语句优化方面去说的,这种优化也有作用,不过是从逻辑方面去优化。但是当所有的逻辑层面已经无可优化,所有的索引都已经加好,表结构也设计的合理,但是遇到高并发的时候,为什么MySQL还是扛不住呢。当然可以通过其他的方面去缓解MySQL的压力,这里我们暂且不谈。对于MySQL而言,我们要尽最大的可能去压榨机器的性能,让所有的计算资源都不浪费,都可以为我们服务。MySQL运行在服务器上,这里特指Linux服务器。那么服务器的硬盘、CPU,内存,网络都有影响到MySQL的性能。MySQl是非常耗费内存的,线上服务器的MySQL内存要吃到80%左右,内存过小,其他的优化空间其实很小。
用户7353950
2022/05/11
1.4K0
浅析interactive_timeout和wait_timeout
一 前言 这篇文章源于自己一个无知的提问,作为一个DBA 老鸟,实在汗颜 。如图,修改wait_timeout参数之后 并没有及时生效,于是乎去跑到技术支持群里问了,其实应该去查g.cn 才对。
用户1278550
2018/08/08
9940
后台报com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failu问题的解决方案
问题: 今早,发现昨天部署的JAVA-WEB服务,不正常启动了,于是查看后台日志,发现
Maynor
2021/12/06
1.5K0
inception安装使用
注意bison版本,centos7如果yum安装bison,会因为版本过高导致编译报错
程序员同行者
2018/08/16
2K0
inception安装使用
Mysql配置文件 扩展详细配置(上)
ON代表打开,OFF代表关闭 1代表打开,0代表关闭 TRUE代表打开,FALSE代表关闭
陈不成i
2021/06/15
1.2K0
MySQL备份问题排查和思考
行内数据库备份在使用某备份软件,使用的数据库版本MySQL 8.0社区版,全备使用mysqldump进行,DBA早上巡检发现有一套数据库全备份失败,心里一疙瘩怎么回事呢?来看看如下报错
老叶茶馆
2021/11/05
1.3K0
MySQL备份问题排查和思考
故障分析 | TCP 缓存超负荷导致的 MySQL 连接中断
在执行跑批任务的过程中,应用程序遇到了一个问题:部分任务的数据库连接会突然丢失,导致任务无法完成。从数据库的错误日志中,发现了 Aborted connection 的信息,这说明客户端和服务器之间的通信被异常中断了。
爱可生开源社区
2024/04/25
4070
故障分析 | TCP 缓存超负荷导致的 MySQL 连接中断
Mysql网络问题处理方法
根据实例上的业务量判断CLOSE_WAIT数量是否超出了正常的范围。TCP连接断开时需要进行四次挥手,TCP连接的两端都可以发起关闭连接的请求,若对端发起了关闭连接,但本地没有关闭连接,那么该连接就会处于CLOSE_WAIT状态。虽然该连接已经处于半开状态,但是已经无法和对端通信,需要及时的释放该连接。建议从业务层面及时判断某个连接是否已经被对端关闭,即在程序逻辑中对连接及时关闭,并进行检查。
mingjie
2022/05/12
1.3K0
数据库炸了——是谁动了我的wait_timeout
  我条件反射的回了句那是接口超时,再多试几次(测试环境的性能比较差,尤其是数据库,经常504
JackieZheng
2019/09/29
8350
数据库炸了——是谁动了我的wait_timeout
12种mysql常见错误总结 +分析示例
小伙伴们好,我是阿沐!最近呢,正筹备上云工作,需要考虑到很多场景;比如mongo、mysql、redis、splinx等等迁移工作,这就涉及到版本兼容问题;在迁移之前,阿沐迁移了mysql到其他容器中,发现迁移机器mysql版本号比较高5.7以上,就出现了sql语句兼容问题。所以趁机会整理了很久以前遇到的各种mysql常见问题跟掘金小伙伴们分享下。小伙伴们可以收藏起来哦,遇到常规错误可以快速查询解决~~~
我是阿沐
2021/06/24
2.5K0
关于mysql的wait_timeout参数 设置不生效的问题
转载自:http://www.cnblogs.com/azhqiang/p/5454000.html
保持热爱奔赴山海
2019/09/18
4.4K0
关于Aborted connection告警日志的分析
有时候,连接MySQL的会话经常会异常退出,错误日志里会看到"Got an error reading communication packets"类型的告警。本篇文章我们一起来讨论下该错误可能的原因以及如何来规避。
MySQL技术
2020/05/19
3.6K0
MySQL Server has gone away 报错原因汇总版
如果uptime数值很大,表明MySQL服务运行了很久了,说明最近服务没有重启过。如果日志没有相关信息,也说明MySQL服务最近没有重启过,可以继续检查下面几项内容。
阿炳数记
2019/02/27
4.2K0
PXC 5.7 mysqldump: Error 2013
最近在mysqldump时,遭遇mysqldump: Error 2013错误。以为是常见的参数设置有问题,调整之后,也没有任何成效。原来发生了OOM,以下是其具体描述。
Leshami
2018/07/31
1.5K0
Mysql配置文件 16c64g优化
一.说明 以下配置适合16核64G及以上的配置,会让性能稍微提高1/3左右。 二.配置 my.cnf [client] port = 3306 socket = /usr/local/mysql/mysql.sock [mysqld] #基础设置 port = 3306 bind-address = 0.0.0.0 lower_case_table_names=1 character-set-server=utf8mb4 default-storage-engine=innoDB basedir=/usr/
陈不成i
2021/06/11
1.3K0
MySQL修改wait_timeout变量global生效session不生效
在一次修改MySQL5.7 wait_timeout变量的时候,配置文件增加wait_timeout = 57600参数后,发现一个非常有意思的现象,如下:
Power
2025/03/01
3460
相关推荐
MySQL占用CPU过高 查找原因及解决 多种方式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验