当在业务逻辑中看到这个错误,或者mysql中使用update语句更新数据报错:Lockwaittimeoutexceeded;tryrestartingtransaction。也就是遇到了mysql死锁,等待资源,事务锁的问题。
可能原因:意外处理没有关闭连接,导致连接过多、或是要更新的表的锁在其它线程手里、系统异常导致事务未提交,再次请求相同记录等等。
InnoDB关于在出现锁等待的时候,会根据参数innodb_lock_wait_timeout的配置(默认50s),判断是否需要进行timeout的操作:
二、mysql死锁排查思路1、showfullprocesslist查询当前数据库全部线程showfullprocesslist查询当前数据库全部线程showengineinnodbstatus命令查看当前的数据库请求,然后再判断当前事务中锁的情况select*frominformation_schema.innodb_trx查询当前运行的全部事务
注:select*frominformation_schema.innodb_trx;MySQL5.5版本以上才可以用此方法,5.5版本以下会没有这个表;[Err]-Unknowntable‘innodb_trx’ininformation_schema当中trx_mysql_thread_id为事务线程的id,參照showfullprocesslist命令中的线程信息查看
如果数据库中有锁的话,LOCKWAIT的就是锁等待的
此时你可以直接使用命令:kill事务线程id杀掉它。比如:kill
没有的话,找到Command状态是query并且Time时间很长的id)有时候一定程度上也能解决一定的问题。
再用showfullprocesslist查询当前数据库全部线程,发现刚才的线程没了。
但是一般这样还是很难发现被锁的行记录问题所在
2、information_schemainformation_schema这张数据表保存了MySQL服务器所有数据库的信息。
我们可以用这三张表innodb_trx、innodb_locks、innodb_lock_waits,使用如下命令,简单地监控当前的事务并分析可能存在的问题:
select*frominformation_schema.innodb_trx(当前运行的所有事务)select*frominformation_schema.innodb_locks(当前出现的锁)select*frominformation_schema.innodb_lock_waits(锁等待的对应关系)
注意:在8.0.1版本中innodb_locks表由performance_schema.data_locks表所代替,innodb_lock_waits表则由performance_schema.data_lock_waits表代替。
三张表具体信息:
其中比较常用的一些列:
trx_id:InnoDB存储引擎内部唯一的事物ID
trx_status:当前事务的状态
trx_status:事务的开始时间
trx_requested_lock_id:等待事务的锁ID
trx_wait_started:事务等待的开始时间
trx_weight:事务的权重,反应一个事务修改和锁定的行数,当发现死锁需要回滚时,权重越小的值被回滚
trx_mysql_thread_id:MySQL中的进程ID,与showprocesslist中的ID值相对应
trx_query:事务运行的SQL语句
综上大体可以清楚的找到等待的事务即没有获取锁的事务,进一步调整业务逻辑代码。
一些建议:1、可以结合update语句,调整索引,让update能唯一定位到数据行,尽量退化到行锁粒度;2、相关查询语句增加索引,减少事物整体耗时;、避免长事物、可以降低
Transactional的粒度;4、减少批处理数据量,规范业务逻辑流程,考虑异常事务回滚等问题;#MYSQL#