文档主页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  InnoDB 中的死锁

17.7.5 InnoDB 中的死锁

死锁是指多个事务无法继续进行的情况,因为每个事务都持有另一个事务所需的锁。由于所有参与的事务都在等待同一资源变得可用,因此它们都没有释放它们持有的锁。

当事务锁定多个表中的行(通过诸如 UPDATESELECT ... FOR UPDATE 之类的语句)但顺序相反时,可能会发生死锁。当此类语句锁定索引记录和间隙的范围,并且每个事务由于时间问题而获取了一些锁但没有获取其他锁时,也会发生死锁。有关死锁示例,请参见 第 17.7.5.1 节,“InnoDB 死锁示例”

为了降低死锁的可能性,请使用事务而不是 LOCK TABLES 语句;确保插入或更新数据的交易足够小,以至于不会长时间保持打开状态;当不同的交易更新多个表或大量行时,在每个交易中使用相同的操作顺序(例如 SELECT ... FOR UPDATE);在 SELECT ... FOR UPDATEUPDATE ... WHERE 语句中使用的列上创建索引。死锁的可能性不受隔离级别影响,因为隔离级别会改变读取操作的行为,而死锁是由于写入操作造成的。有关避免和恢复死锁条件的更多信息,请参见 第 17.7.5.3 节,“如何最小化和处理死锁”

当启用死锁检测(默认情况下)并且发生死锁时,InnoDB 会检测到这种情况并回滚其中一个事务(受害者)。如果使用 innodb_deadlock_detect 变量禁用死锁检测,InnoDB 将依赖于 innodb_lock_wait_timeout 设置在发生死锁的情况下回滚事务。因此,即使您的应用程序逻辑正确,您仍然必须处理必须重试事务的情况。要查看 InnoDB 用户事务中的最后一次死锁,请使用 SHOW ENGINE INNODB STATUS。如果频繁的死锁突出了事务结构或应用程序错误处理的问题,请启用 innodb_print_all_deadlocks 将有关所有死锁的信息打印到 mysqld 错误日志中。有关如何自动检测和处理死锁的更多信息,请参见 第 17.7.5.2 节,“死锁检测”