MySQL官方文档14.5.5.2 死锁检测和回滚

原文地址:https://dev.mysql.com/doc/refman/5.7/en/innodb-deadlock-detection.html

14.5.5.2 死锁检测和回滚

当启用死锁检测时(默认),InnoDB会自动检测事务死锁并回滚一个或多个事务来打破死锁。InnoDB会尝试选择小型事务进行回滚,其中事务的大小由插入,更新或删除的行数决定。

如果innodb_table_locks = 1(缺省值)和autocommit = 0,InnoDB知道表锁,并且它上面的MySQL层知道行级锁。否则,InnoDB无法检测由MySQL LOCK TABLES语句设置的表锁或由InnoDB以外的存储引擎设置的锁所导致的死锁。通过设置innodb_lock_wait_timeout系统变量的值来解决这些情况。

当InnoDB执行的事务完成回滚时,将释放事务设置的所有锁。但是,如果只有一条SQL语句由于错误而回滚,则该语句设置的某些锁可能会被保留。发生这种情况是因为InnoDB以一种格式存储行锁,以致于它无法知道哪个锁由哪个语句设置。

如果SELECT在事务中调用存储的函数,并且函数中的语句失败,那么该语句将回滚。此外,如果在此之后执行ROLLBACK,则整个事务回滚。

如果InnoDB Monitor输出的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个锁,则也会发生同样的错误。

有关组织数据库操作以避免死锁的技术,请参见第14.5.5节“InnoDB中的死锁”。

禁用死锁检测

在高并发系统上,当大量线程等待相同的锁时,死锁检测会导致速度下降。有时,在死锁发生时,禁用死锁检测并依赖innodb_lock_wait_timeout设置进行事务回滚可能更有效。使用innodb_deadlock_detect配置选项可以禁用死锁检测。

你可能感兴趣的:(MySQL)