InnoDB的死锁检测是通过等待图(Wait-For-Graph)的算法实现的,即检查所有在一个锁上等待的事务是否已经成环;如果成环了说明已经出现死锁,根据一定的策略将某个事务回退将环切断而解除死锁。
死锁的检测时机是在将事务加入等待队列是检测的(lock_table_enqueue_waiting(表), lock_rec_enqueue_waiting(记录) );死锁检测函数lock_deadlock_occurs->lock_deadlock_recursive
- 表锁
- 记录(行)锁
由于记录锁是采用哈希来管理的,因此需要查找当前页所在哈希桶的所有锁,找到当前记录的所有的锁,并查看这些锁的事务是否成环,如果成环,则说明已经产生了死锁,根据事务的权重来判断回滚哪个事务。
- 还有,由于死锁检测采用递归的方式检测的,如果递归层次超过LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK(200)或搜索节点的个数超过LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK(1000000),则表示调用层次太深,或者调用次数过多,返回LOCK_EXCEED_MAX_DEPTH,也表示死锁产生了。