问题现象
测试ddos持续攻击,防护程序频繁读写数据库,mysql处理报错。同时进行接口调用,接口响应时间较长,耗时几十秒才返回错误提示,两者错误日志均为 Error 1205: Lock wait timeout exceeded; try restarting transaction
问题原因
Error number: 1205; Symbol: ER_LOCK_WAIT_TIMEOUT; SQLSTATE: HY000
Message: Lock wait timeout exceeded; try restarting transaction
InnoDB reports this error when lock wait timeout expires. The statement that waited too long was rolled back (not the entire transaction). You can increase the value of the innodb_lock_wait_timeout configuration option if SQL statements should wait longer for other transactions to complete, or decrease it if too many long-running transactions are causing locking problems and reducing concurrency on a busy system.
翻译:
当锁等待超时后innodb引擎报此错误,等待时间过长的语句被回滚(不是整个事务)。如果想让SQL语句等待其他事务更长时间之后完成,你可以增加参数innodb_lock_wait_timeout配置的值。如果有太多长时间运行的有锁的事务,你可以减小这个innodb_lock_wait_timeout的值,在特别繁忙的系统,你可以减小并发。
Mysql数据库采用InnoDB引擎,InnoDB事务等待一个行级锁的时间最长时间(单位是秒),超过这个时间就会放弃。默认值是50秒。一个事务A试图访问一行数据,但是这行数据正在被另一个innodb事务B锁定,此时事务A就会等待事务B释放锁,等待超过innodb_lock_wait_timeout设置的值就会报错ERROR 1205 (HY000)。 附:查看行锁阈值
问题场景
- 在同一事务内先后对同一条数据进行插入和更新操作;
- 多台服务器操作同一数据库;
- 瞬时出现高并发现象;(不同事务同时插入更新同一条数据)
解决方法
一 :可以尝试修改 innodb_lock_wait_timeout 值(1-1073741824秒)
mysql> set GLOBAL innodb_lock_wait_timeout=1500;
关于set innodb_lock_wait_timeout=1500; 和 set global innodb_lock_wait_timeout=1500;的区别。前者等价于set session只影响当前session,后者作为全局的修改方式,只会影响修改之后打开的session;注意后者不能改变当前session;