mysql又很多参数和变量(500+), 虽然大部分都不需要去管, 但遇到问题/报错的时候往往会和这些参数有关. 所以我们就简单的解析mysql一些常见的参数. 按照类型来看, 比如本文的超时(timeout)类
(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 | 全局 | 是 | 2 -- 31536000 (单位:秒) | 10 | 连接超时 |
该参数是服务端发送handshake包给客户端, 然后等待客户端返回handshakeResponse,等待connect_timeout秒未收到相关报文则连接失败, 并记录日志:Note Server Got timeout reading communication packets
通过源码发现, 这个参数其实比较特殊:
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_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
连上数据库后没想好干啥, 等敲好sql并回车后收到如下信息:
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
这里得分两种情况:
服务器是怎么区分是交互式的还是非交互式的呢? 我们翻翻连接协议, 发现有个capability_flags
其中CLIENT_INTERACTIVE就是表示客户端是否是交互式的.
既然长时间不发sql会超时, 那我们赶紧发一条SQL. 但是又收到如下信息:
(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, 但还是报一样的错
(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 删除。