一文了解MySQL性能测试及调优中的死锁处理方法,你还看不明
死锁检测
通过SQL语句查询锁表相关信息:
(1)查询表打开情况SHOWOPENTABLESWHEREINUSE0
(2)查询锁情况列表SELECTFROMINFORMATIONSCHEMA。INNODBLOCKS
(3)查询锁等待信息,其中blockinglockid是当前事务在等待的事务SELECTFROMINFORMATIONSCHEMA。INNODBLOCKWAITS
(4)查询死锁日志SHOWENGINEINNODBSTATUS
这条语句只能显示最新的一条死锁,无法完全捕获到系统发生的所有死锁信息。
如果想要记录所有的死锁日志,需要打开innodbprintalldeadlocks参数,将所有的死锁日志记录到errorlog中。
(5)查询锁等待时间SHOWSTATUSLIKElock死锁避免
当有死锁发生时,通常是由于项目的程序中出现了冗长的事务,或是由于隔离级别设置的不合适等。
我们需要在事务使用中注意以下几点:
(1)尽量保持事务的短小精悍,做出一系列关联的更新操作后立即提交事务,以降低死锁的可能性。特别是不要让有关联的MySQL会话长时间挂起未提交的事务。
(2)建议使用更低的隔离级别,如READCOMMITTED。
(3)在同一事务内修改多张表,或一张表内的不同行时,每次以相同的顺序执行操作。以便让事务形成清晰的锁操作队列而规避死锁。死锁解决
MySQL数据库通过死锁检测(innodbdeadlockdetect)和死锁超时时间(innodblockwaittimeout)这两个参数来进行死锁解决。
死锁检测(innodbdeadlockdetect):在MySQL8。0中,增加了一个新的动态变量innodbdeadlockdetect,用来控制InnoDB是否执行死锁检测。
该参数的默认值为ON,即打开死锁检测。开启后InnoDB在加锁的时候会检测加锁后是否会造成死锁,如果会加锁,就回滚代价最小的那一个事务。
死锁超时时间(innodblockwaittimeout):这个参数可以用来处理检测不出来的死锁,或是避免长时间等待较长的事务的情况。
对于高并发的系统,当大量线程等待同一个锁时,死锁检测可能会导致性能的下降。
此时,如果禁用死锁检测,而改为依靠参数innodblockwaittimeout来释放长时间占用锁资源的事务可能会更加高效。
也就是说,在确认死锁检测功能影响了系统的性能并且禁用死锁检测不会带来负面影响时,可以尝试关闭innodbdeadlockdetect选项。
另外,如果禁用了InnoDB死锁检测,需要及时调整参数innodblockwaittimeout的值,以满足实际的需求。