死锁检测是默认开启的。开启死锁检测后,InnoDB会自动检测死锁,并回滚某个事务来结束死锁循环。InnoDB会尝试选择一个小事务来回滚。事务的
大小取决于插入、更新或删除的行数。
如果innodb_table_locks = 1且autocommit=0,InnoDB会检测到表锁,而MySQL层知道行级锁。否则,InnoDB无法检测到lock tables语句
造成的死锁。通过设置system级的变量innodb_lock_wait_timeout可以解决这个问题。
如果InnoDB监控输出信息中的LATEST DETECTED DEADLOCK段包含了这样一条消息"TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITES-FOR
GPAPH,WE WILL ROLL BACK FOLLOWING TRANSACTION",说明处于等待状态的事务数量超过了200。如果等待的事务数量超过200,会被当成死锁,尝试检测
等待列表的事务会被回滚。如果加锁线程要检查的锁的数量超过100万,也会产生同样的错误。
在高并发系统中,死锁检测会导致性能下降。有时,禁用死锁检测,依靠innodb_lock_wait_timeout设置可能更高效。可以通过innodb_dead_lock_detect
变量来禁用死锁检测。
15.7.5.2 死锁检测