MySQL 8.3 Release Notes
当 死锁检测 启用(默认情况下),InnoDB
自动检测事务 死锁 并回滚事务以打破死锁。 InnoDB
尝试回滚小事务,其中事务的大小由插入、更新或删除的行数确定。
InnoDB
如果 innodb_table_locks = 1
(默认情况下)和 autocommit = 0
,则了解表锁,并且 MySQL 层知道行级锁。否则,InnoDB
无法检测死锁,其中包括 MySQL LOCK TABLES
语句或其他存储引擎设置的锁。解决这些情况可以通过设置 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
设置来回滚事务可能更高效。可以使用 innodb_deadlock_detect
变量禁用死锁检测。