Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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节,“Deadlock Detection”