Day88 【概念解析】死锁检测
行业概念

Day88 【概念解析】死锁检测

· 约 1,335 字 · 阅读约 7 分钟
目录

整理定义

死锁检测(Deadlock Detection)

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

如果 innodb_table_locks = 1(默认值)且 autocommit = 0,则 InnoDB 会意识到表锁,而它上方的 MySQL 层知道行级锁。 否则,InnoDB 无法检测涉及 MySQL LOCK TABLES 语句设置的表锁或 InnoDB 以外的存储引擎设置的锁的死锁。 通过设置 innodb_lock_wait_timeout 系统变量的值来解决这些情况。

如果 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 个锁,也可能会发生相同的错误。

禁用死锁检测

在高并发系统上,当大量线程等待同一锁时,死锁检测可能会导致速度减慢。 有时,禁用死锁检测并在发生死锁时依靠 innodb_lock_wait_timeout 设置进行事务回滚可能会更有效。 可以使用 innodb_deadlock_detect 变量禁用死锁检测。

复述展开

Deadlock Detection

理解体会

在InnoDB中,死锁检测是一个重要的功能,它可以自动检测并解决事务死锁的问题。事务死锁是指两个或更多的事务在等待对方释放资源,从而导致所有事务都无法继续进行的情况。

当启用死锁检测(默认情况下是启用的)时,InnoDB会自动检测这种死锁情况,并选择一个或多个事务进行回滚,以打破死锁。InnoDB通常会选择较小的事务进行回滚,这里的”小”是指事务涉及的行数较少。

InnoDB可以感知到表级别的锁,如果设置了innodb_table_locks = 1(默认值)和autocommit = 0。然而,如果死锁涉及的是由MySQL的LOCK TABLES语句或者由其他存储引擎设置的锁,InnoDB则无法检测到。在这种情况下,可以通过设置innodb_lock_wait_timeout系统变量的值来解决。

在某些情况下,例如高并发系统中,死锁检测可能会导致性能下降,因为可能有大量的线程在等待同一把锁。在这种情况下,可能更有效的策略是禁用死锁检测,而依赖于innodb_lock_wait_timeout设置来在发生死锁时进行事务回滚。可以通过设置innodb_deadlock_detect变量来禁用死锁检测。

总的来说,InnoDB的死锁检测是一个强大的工具,可以帮助数据库自动解决可能的死锁问题,但在某些情况下,可能需要进行一些调整以优化性能。

相关文章