最近在看mysql技术内幕这本书,分享一些阅读笔记
innoDB存储引擎主要实现了以下两种标准的行级锁:
1、共享锁:允许事务读一行数据。
2、排他锁:允许事务删除或更新一行数据。
如果一个事务T1已经获得了行r的共享锁,那么另外的事务T2可以立即获得行r的共享锁,因为读取并没有改变行r的数据,称这种情况为锁的兼容性,若有事务T3想要获得行r的排他锁,则必须等待T1和T2 释放行r的共享锁,这种情况称为锁的不兼容性
以下列出了排他锁X和共享锁S的兼容情况
我们可以发现X锁与任何的锁都不兼容,而S锁和S锁兼容,需要注意的是,S锁和X锁都是行级锁,兼容是指同一记录锁的兼容情况
innoDB还支持了多粒度锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在,为了满足不同粒度上的骚操作,innoDB引出了一种额外的锁------意向锁,意向锁将锁定的对象分为多个层次,意味着事务希望在更细粒度上加锁
要想事务在细粒度上加锁,则需要先在粗粒度上加锁,这就好比一棵树,先要有根再发芽,如上图所示,如果需要在记录上加锁,则需要在数据库、表、页上加意向锁,如果任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成
举例来说,如果一个事务在对一个记录做了共享锁,那么此时其他事务需要对同一行记录做排他锁的时候,同一行 记录 所在的表上会有一个意向锁,由于共享锁和排他锁的不兼容性,所以其他事务需要等待表锁操作的完成才行。
innoDB中的意向锁其实就是表级锁,设计的目的主要是为了在事务中,揭示下一行将被请求的锁类型,更好的达到兼容性的目的,其支持两种意向锁:
1、意向共享锁(LS),事务想要获取一张表中某几行的共享锁
2、意向排他锁(LX),事务想要获取一张表中某几行的排他锁
由于innoDB支持的行级别的锁,因此意向锁不会阻塞除了全表扫描以外的任何请求,所以全表扫描之所以慢,也有这部分原因,下面是表级锁与行级锁的兼容性