Mysql中InnoDB引擎的锁
锁这种机制的作用:对共享资源并发访问的管理,保证数据的完整性和一致性。
lock与latch
在数据库中,lock与latch都可以被称为”锁“,但是两者的含义是完全不同的。
lock针对的对象是事务,它用来锁定数据库中的对象,如表、页、行。一般lock的对象仅在事务commit或者rollback后进行释放,并且lock是有死锁机制的。
latch一般称为闩锁(轻量级的锁),因为其要求的锁定时间必须非常短,若持续的时间长,则应用的性能会非常差。在InnoDB存储引擎中,latch又可以分为mutex(互斥量)和 rwlock(读写锁)。latch的目的是保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。
锁的类型
InnoDB存储引擎实现了如下两种标准的行级锁:共享锁(S Lock)和排他锁(X Lock)。
共享锁:事务要想读取一行数据,需要获取共享锁。
排他锁:允许事务删除或者更新一行数据。
共享锁与排他锁的兼容性如下表:
X | S | |
X | 不兼容 | 不兼容 |
S | 不兼容 | 兼容 |
InnoDB存储引擎支持多粒度(granular)锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在。为了支持在不同粒度上进行加锁操作,InnoDB存储引擎支持一种额外的锁方式,称之为意向锁(Intention Lock)。
InnoDB存储引擎的意向锁设计比较简练,其意向锁即为表级别的锁。设计目的主要是为了在一个事务中揭示下一行将被请求的锁类型。支持的意向锁有两种:意向共享锁(IS Lock)和意向排他锁(IX Lock):
IS Lock:事务想要获取一张表中某几行的共享锁;
IX Lock:事务想要获取一张表中某几行的排他锁。
意向锁是将锁定的对象分为多个层次,如果需要对页上的记录进行上X锁,那么分别需要对数据库、表、页上意向锁IX,最后对记录上X锁。若其中任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成。
由于InnoDB存储引擎支持的是行级别的锁,因此意向锁其实不会阻塞除全表扫以外的任何请求。表级意向锁与行级锁的兼容性如下表:
IS | IX | S | X | |
IS | 兼容 | 兼容 | 兼容 | 不兼容 |
IX | 兼容 | 兼容 | 不兼容 | 不兼容 |
S | 兼容 | 不兼容 | 兼容 | 不兼容 |
X | 不兼容 | 不兼容 | 不兼容 | 不兼容 |