MySQLInnoDB存储引擎之锁(三)

2015-01-23 22:07:59 · 作者: · 浏览: 14
夺资源而造成的一种相互等待的现象。解决死锁最简单的一种方式是超时,即当两个事务相互等待是,当一个等待时间超过设置的某一阀值时,其中一个事务进行回滚,另外一个等待的事务就能继续进行。在InnoDB存储引擎中,参数innodb_lock_wait_timeout用来设置超时时间。但若超时的事务所占权重比较大,如果事务操作更新了很多行,占用了较多的undo log,这时采用FIFO的方式就不合适啦,因为回滚这个事务的时间相对于另一个事务所占用的时间可能会很多。因此,除了超时机制,当前数据库都普遍采用wait-for graph(等待图)的方式来进行死锁检测。要求数据库报错以下两种信息:a.锁的信息链表;b.事务等待链表。通过上述链表可以构造一张图,而在这个图中若存在回路,就代表存在死锁。在wait-for graph中,事务为图中的节点。如图:

如图可以发现存在回路(1,2),因此存在死锁,这时InnoDB存储引擎选择回滚undo量最小的事务。wait-for graph的死锁检测通常采用深度优先的算法实现。
注意:
1.S X IS IX,表示的是,本锁和其他锁共存的方式,是互斥还是兼容
2.RECORD LOCK、GAP LOCK、NEXT-KEY LOCK,表示的是,这些锁要加载的范围,是行记录本身,还是行记录+间隙,甚至更大的范围
重要的结论:
1、任何辅助索引上的锁,或者非索引列上的锁,最终都要回溯到主键上,在主键上也要加一把锁
2、任何叶子节点上的S或X锁之前,都会在根节点加一个IS或IX锁,也就是表级别的IS、IX锁
3、主键索引上的锁,都是record lock
4、唯一索引辅助索引上的锁,也都是record lock
5、非唯一索引辅助索引上的锁,则是next-key lock
6、不会有单独的gap lock出现,只会伴随着record lock出现,依附于它