首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[MYSQL] 参数/变量浅析(1) -- 超时(timeout)相关

[MYSQL] 参数/变量浅析(1) -- 超时(timeout)相关

原创
作者头像
大大刺猬
发布2025-07-03 17:56:44
发布2025-07-03 17:56:44
1240
举报
文章被收录于专栏:大大刺猬大大刺猬

导读

mysql又很多参数和变量(500+), 虽然大部分都不需要去管, 但遇到问题/报错的时候往往会和这些参数有关. 所以我们就简单的解析mysql一些常见的参数. 按照类型来看, 比如本文的超时(timeout)类

代码语言:txt
复制
(root@127.0.0.1) [(none)]> show global variables like '%timeout%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| have_statement_timeout      | YES      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 60       |
| wait_timeout                | 28800    |
+-----------------------------+----------+

如果是8.0的话, 还有mysqlx_XXX,replica_net_timeout,rpl_stop_replica_timeout,rpl_stop_replica_timeout参数. 看着就令人头大.

connect_timeout

当我们从客户端连接到服务端的时候, 会遇到connect_timeout.

参数名

生效范围

是否动态

取值范围

默认值

描述

connect_timeout

全局

2 -- 31536000 (单位:秒)

10

连接超时

该参数是服务端发送handshake包给客户端, 然后等待客户端返回handshakeResponse,等待connect_timeout秒未收到相关报文则连接失败, 并记录日志:Note Server Got timeout reading communication packets

通过源码发现, 这个参数其实比较特殊:

代码语言:c++
复制
bool thd_prepare_connection(THD *thd) {
  thd->enable_mem_cnt();
  bool rc;
  lex_start(thd);
  rc = login_connection(thd);
  if (rc) return rc;
  prepare_new_connection_state(thd);
  return false;
}

static bool login_connection(THD *thd) {
    ....
  thd->get_protocol_classic()->set_read_timeout(connect_timeout, true);
  thd->get_protocol_classic()->set_write_timeout(connect_timeout);
    ....
  thd->get_protocol_classic()->set_read_timeout(
      thd->variables.net_read_timeout);
  thd->get_protocol_classic()->set_write_timeout(
      thd->variables.net_write_timeout);
  ....
}

该参数实际上是连接阶段篡夺了net_write和net_read的超时

net_read_timeout/set_write_timeout

那么"被篡夺者"net_read_timeoutset_write_timeout又是干啥的呢?

参数名

生效范围

是否动态

取值范围

默认值

描述

net_read_timeout

全局/会话

1 -- 31536000(单位:秒)

30

从客户端读取数据的超时时间

net_write_timeout

全局/会话

1 -- 31536000(单位:秒)

60

给客户端发包时的超时时间

这俩其实就是服务端收发客户端包时的超时参数, 比如以服务端收包(net_read_timeout)时: 接受客户端sql语句时的超时时间. 超时则会报错:MY-010914 Got timeout reading communication packets

例子: sql语句+包一共148字节, 但客户端先发送100字节, 过了40秒再发送剩余的48字节. 然后服务端日志就会有提示MY-010914 (需要设置log_error_verbosity=3才能看到note级别的信息)

net_write_timeout同理, 只不过note信息变为了Got timeout writing communication packets

wait_timeout/interactive_timeout

连上数据库后没想好干啥, 等敲好sql并回车后收到如下信息:

代码语言:txt
复制
ERROR 4031 (HY000): The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.
No connection. Trying to reconnect...
Connection id:    37
Current database: *** NONE ***

参数名

生效范围

是否动态

取值范围

默认值

描述

interactive_timeout

全局/会话

1-31536000(秒)

28800

交互式空闲超时

wait_timeout

全局/会话

1-31536000(秒)(windows:1-2147483)

28800

非交互式空闲超时

原来是超时了, 啥也不干, 光占着连接, 就被服务器踢了.

如果我们连接后偷偷掉线, 服务器会记录Got an error reading communication packets

这里得分两种情况:

  1. 非交互式连接. 这种通常是业务连接, 使用wait_timeout来设置空闲超时时间.
  2. 交互式连接, 这种通常是dba使用mysql连接过来的, 不能和业务一样的处理方法, 我们使用interactive_timeout来记录空闲时间.

服务器是怎么区分是交互式的还是非交互式的呢? 我们翻翻连接协议, 发现有个capability_flags

其中CLIENT_INTERACTIVE就是表示客户端是否是交互式的.

lock_wait_timeout/innodb_lock_wait_timeout

既然长时间不发sql会超时, 那我们赶紧发一条SQL. 但是又收到如下信息:

代码语言:txt
复制
(root@127.0.0.1) [(none)]> delete from db1.t20250703_2 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

该信息表示事务获取锁超时, 当我们读取一张表的时候, 会先获取表的读意向锁(MDL),但是有其它会话持有这个表的X锁, 导致我们获取锁超时. 即表锁. 等待时间由lock_wait_timeout控制

于是赶紧把那个会话kill了. 然后再次跑该sql, 但还是报一样的错

代码语言:txt
复制
(root@127.0.0.1) [(none)]> delete from db1.t20250703_2 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

这次等的是行锁了, 我们可以通过performance_schema.data_locks查看. 等待超时时间由innodb_lock_wait_timeout控制. (innodb才支持事务, 所以这个参数只对innodb表有效, 从名字也能看出来.)

参数名

生效范围

是否动态

取值范围

默认值

描述

lock_wait_timeout

全局/会话

1-31536000(秒)

31536000

表锁超时时间

innodb_lock_wait_timeout

全局/会话

1-1073741824(秒)

50

行锁超时时间

然后我们可以等待其它事务执行完成,再继续, 执行完成之后, 我们就可以commit了, commit的时候是否有相关超时呢? (不用考虑半同步之类的)

总结

本次简单的介绍了几个超时相关的参数, 方便后续看到超时报错的时候知道是啥导致的. 做下汇总表吧:

参数名

生效范围

是否动态

取值范围

默认值

描述

connect_timeout

全局

2 -- 31536000 (单位:秒)

10

连接超时

net_read_timeout

全局/会话

1 -- 31536000(单位:秒)

30

从客户端读取数据的超时时间

net_write_timeout

全局/会话

1 -- 31536000(单位:秒)

60

给客户端发包时的超时时间

interactive_timeout

全局/会话

1-31536000(秒)

28800

交互式空闲超时

wait_timeout

全局/会话

1-31536000(秒)(windows:1-2147483)

28800

非交互式空闲超时

lock_wait_timeout

全局/会话

1-31536000(秒)

31536000

表锁超时时间

innodb_lock_wait_timeout

全局/会话

1-1073741824(秒)

50

行锁超时时间

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导读
  • connect_timeout
  • net_read_timeout/set_write_timeout
  • wait_timeout/interactive_timeout
  • lock_wait_timeout/innodb_lock_wait_timeout
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档