场景:有两个会话,其中会话1在事务操作,会话2在等待这个事务操作完成,然后会有这个报错产生。
通过查询资料,在这里整理一下。
一:总结timeout参数的作用
1.操作
2.具体解释
1)connect_timeout
The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake
Increasing the connect_timeout value might help if clients frequently encounter errors of the form Lost connection to MySQL server at 'XXX', system error: errno.
翻译:mysql服务等待连接包的时间(单位秒),超过这个时间就会抛出'坏握手'的响应。如果客户端经常遇到形如:Lost connection to MySQL server at 'XXX', system error: errno的错误,那么增加connect_timeout的值可以有所帮助;
说下mysql处理客户端请求的过程:
mysql的基本原理应该是有个监听线程循环接收请求,当有请求来时,创建线程(或者从线程池中取)来处理这个请求。由于mysql连接采用TCP协议,那么之前势必是需要进行TCP三次握手的。TCP三次握手成功之后,客户端会进入阻塞,等待服务端的消息。服务端这个时候会创建一个线程(或者从线程池中取一个线程)来处理请求,主要验证部分包括host和用户名密码验证。host验证我们比较熟悉,因为在用grant命令授权用户的时候是有指定host的。用户名密码认证则是服务端先生成一个随机数发送给客户端,客户端用该随机数和密码进行多次加密后发送给服务端验证。如果通过,整个连接握手过程完成
2)delayed_insert_timeout
insert delay操作延迟的秒数,这里不是insert操作,而是insert delayed,延迟插入。 该参数再以后即将被遗弃,可不关注!
3)innodb_flush_log_at_timeout
这个是5.6中才出现的,是InnoDB特有的参数,日志刷新时间间隔,默认是1秒
4)innodb_lock_wait_timeout
InnoDB事务等待一个行级锁的时间最长时间(单位是秒),超过这个时间就会放弃。默认值是50秒
5)innodb_rollback_on_timeout
在innodb中,如果这个参数为 on,那么当事务中的最后一个语句超时的时候,就会回滚这个事务,默认是off,关闭状态。
6)interactive_timeout (交互式) 和wait_timeout(非交互式)
交互式和非交互式链接的超时设置,防止客户端长时间链接数据库,什么都不做处于sleep状态,强制关闭长时间的sleep链接。
还是先看官方文档,从文档上来看wait_timeout和interactive_timeout都是指不活跃的连接超时时间,连接线程启动的时候wait_timeout会根据是交互模式还是非交互模式被设置为这两个值中的一个。如果我们运行mysql -uroot -p命令登陆到mysql,wait_timeout就会被设置为interactive_timeout的值。如果我们在wait_timeout时间内没有进行任何操作,那么再次操作的时候就会提示超时,这需要mysql client重新连接。默认情况先两值的都为28800(8h),一般情况下将两值都设置为1000s就行了。
7)lock_wait_timeout
获取元数据锁的超时时间。这个适合用于除了系统表之外的所有表(mysql库之外)。
区别于innodb_lock_wait_timeout是针对dml操作的行级锁的等待时间 ,而lock_wait_timeout是数据结构ddl操作的锁的等待时间
区别于innodb_lock_wait_timeout是针对dml操作的行级锁的等待时间 ,而lock_wait_timeout是数据结构ddl操作的锁的等待时间
8)
net_read_timeout
net_write_timeout
这两个表示数据库发送网络包和接受网络包的超时时间。
9)rpl_stop_slave_timeout(默认值即可,无需修改)
在 5.6.13开始以及以后的版本中,可以通过这个参数控制stop slave 的执行时间,在重放一个大的事务的时候,突然执行stop slave,命令 stop slave会执行很久(时间设置的太短会time out),这个时候可能产生死锁或阻塞,严重影响性能,默认值和最大值都是31536000秒(一年)
10)slave_net_timeout
The number of seconds to wait for more data from the master before the slave considers the connection broken, aborts the read, and tries to reconnect. The first retry occurs immediately after the timeout. The interval between retries is controlled by the MASTER_CONNECT_RETRY option for the CHANGE MASTER TO statement, and the number of reconnection attempts is limited by the --master-retry-count option. The default is 3600 seconds (one hour).
翻译:从库等待主库更多的数据的时间,超过这个时间(默认值是3600 ),slave就认为这个连接有问题了,并且终止继续读取主库的变化,尝试从新连接主库。等待超时后立马尝试第一次从新连接,之后重连的时间间隔由CHANGE MASTER TO 的时候指定 MASTER_CONNECT_RETRY=的值 控制,重连的次数由CHANGE MASTER TO 的时候指定master-retry-count=的值 控制。
二:解决
1.针对本问题的解释
当锁等待超时后innodb引擎报此错误,等待时间过长的语句被回滚(不是整个事务)。如果想让SQL语句等待其他事务更长时间之后完成,你可以增加参数innodb_lock_wait_timeout配置的值。如果有太多长时间运行的有锁的事务,你可以减小这个innodb_lock_wait_timeout的值,在特别繁忙的系统,你可以减小并发。
InnoDB事务等待一个行级锁的时间最长时间(单位是秒),超过这个时间就会放弃。默认值是50秒。一个事务A试图访问一行数据,但是这行数据正在被另一个innodb事务B锁定,此时事务A就会等待事务B释放锁,等待超过innodb_lock_wait_timeout设置的值就会报错ERROR 1205 (HY000)
2.理论值
innodb_lock_wait_timeout是动态参数,默认值50秒,最小值是1秒,最大值是1073741824;
3.setinnodb_lock_wait_timeout=1500; 和 set global innodb_lock_wait_timeout=1500;的区别。
前者等价于set session只影响当前session,后者作为全局的修改方式,只会影响修改之后打开的session;注意后者不能改变当前session;
4.调大参数
5.重新实验
时间更久后的实验,目前是没有问题了。
没有出现锁表的问题,因为,这里只是简单的实验,不会出现那个情况。