MySQL 8.4 Release Notes
17.7.5.2 死锁检测
当死锁检测启用(默认情况下),InnoDB
自动检测事务死锁并回滚事务或事务以解除死锁。InnoDB
尝试选择小的事务回滚,其中事务的大小由插入、更新或删除的行数确定。
InnoDB
如果innodb_ table_locks = 1
(默认情况下)和autocommit = 0
,那么它知道表锁定;否则,如果MySQLLOCK TABLES
语句或其他存储引擎设置的锁定涉及到死锁,那么InnoDB
无法检测这些情况。解决这些情况可以通过设置innodb_lock_wait_timeout
系统变量的值。
如果 InnoDB
监控输出的LATEST DETECTED DEADLOCK
部分包含一条消息,指出TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL ROLL BACK FOLLOWING TRANSACTION,这表明等待列表中的事务数量已经达到200个。超过200个事务的等待列表将被视为死锁,并且尝试检查等待列表的事务将被回滚。同样,这个错误也可能发生在锁定线程需要查看等待列表中超过1,000,000个事务所有锁的情况下。
要了解避免死锁的数据库操作技巧,请参阅第17.7.5节,“InnoDB 中的死锁”。
禁用死锁检测
在高并发系统中,死锁检测可能会导致许多线程等待同一个锁时的性能下降。在某些情况下,禁用死锁检测,并且依靠innodb_lock_wait_timeout
变量来 rollback 事务时遇到死锁可能更为高效。可以使用innodb_deadlock_detect
变量来禁用死锁检测。