当启用死锁检测(默认)时,
InnoDB
自动检测事务
死锁并回滚一个或多个事务以打破死锁。
InnoDB
尝试挑选小事务回滚,其中事务的大小由插入、更新或删除的行数决定。
InnoDB
如果
innodb_table_locks = 1
(默认)和
知道表锁autocommit = 0
,并且它上面的 MySQL 层知道行级锁。否则
InnoDB
无法检测出涉及MySQLLOCK TABLES
语句设置的表锁或非存储引擎设置的锁的
死锁InnoDB
。innodb_lock_wait_timeout
通过设置系统变量
的值来解决这些情况
。
如果Monitor 输出LATEST DETECTED DEADLOCK
部分
包含一条消息,说明TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL BACK FOLLOWING TRANSACTION,这表明等待列表上的事务数已达到 200 的限制. 超过 200 个事务的等待列表被视为死锁,并回滚试图检查等待列表的事务。如果锁定线程必须查看等待列表中的事务所拥有的超过 1,000,000 个锁,也可能会发生相同的错误。
InnoDB
有关组织数据库操作以避免死锁的技术,请参阅第 15.7.5 节,“InnoDB 中的死锁”。
在高并发系统上,当大量线程等待同一个锁时,死锁检测会导致速度减慢。innodb_lock_wait_timeout
有时,禁用死锁检测并依赖发生死锁时事务回滚的设置可能更有效
。可以使用该
innodb_deadlock_detect
变量禁用死锁检测。