Innodb的锁机制
innodb中有行锁、间隙锁、表锁。其中表锁属于server层实现,不同的存储引擎都有表锁。而行锁、间隙锁属于存储引擎层的实现,只有innodb引擎才有。
表锁的实现
在server层,每个表都有一个表对象。这个表对象中有两个链表,分别为获取到的列表和等待获取锁的列表。线程获取到锁时先创建一个MDL_ticket对象,记录获取锁的线程、事务id、线程id、锁类型(共享锁(S锁)或排他锁(X锁))等信息,然后将这个对象加入到获取到的列表中。未获取到锁的线程则将MDL_ticket对象添加到等待获取锁的列表,阻塞线程。
行锁的实现
行锁和间隙锁是innodb中的特性,间隙锁是行锁的特殊形式。他们都是以行锁的记录存于innodb的全局锁哈希表中,key为表空间ID、页号和记录号。value为锁对象。锁对象包含了锁的类型(共享锁、排他锁、间隙锁等)、被锁定的记录以及锁定该记录的事务信息。行锁的实现主要由全局锁哈希表和锁等待队列配合完成工作。线程在获取行锁时,如果在全局锁哈希表中未检查到锁冲突,则生成对应的锁对象添加到全局锁哈希表中。如果产生了锁冲突,则将当前事务的锁请求放入锁定队列。如果在等待未超时期间锁被释放,则从锁定队列中取出一个事务获取锁,否则,一旦等待超时,则事务被回滚。
总结: 一个请求过来时,会先到达server层检查是否有表锁冲突,然后进入存储引擎层判断是否有行锁冲突。