文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  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 节,“死锁检测”