一、什么是锁
锁是数据库系统区别于文件系统的一个关键特性。锁机制用于管理对共享资源的并发访问。
数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。
InnoDB存储引擎锁的实现和Oracle数据库很相似,提供一致性的非锁定读、行级锁支持。行级锁没有相关额外的开销,并可以同事得到并发性和一致性。
二、lock与latch
lock和latch都可以被称为“锁”。但是两者有着不同的意义。
latch一般称为闩锁(轻量级的锁),因为其要求锁定的时间必须非常短。若持续的时间长,则应用的性能会非常差。
在InnoDB存储引擎中,latch又可分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,通常没有死锁检测的机制。
lock的对象是事务,用来锁定的是数据库的对象,如表,页,行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。此外,lock,在大多数据库中,是有死锁机制的。
如图:lock与latch的比较
对于InnoDB存储引擎中latch,可以通过命令 SHOW ENGINE INNODB MUTEX来进行查看。
通过命令SHOW ENGINE INNODB STATUS及information_schema架构下的表INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS来观察锁的信息。
三、锁的类型
InnoDB存储引擎实现了如下两种标准的行级锁:
1》、共享锁(S Lock),允许事务读取一行的数据
2》、排它锁(X Lock),允许事务删除或更新一行数据
如果一个事务T1已结获得了行R的共享锁,那么另外的事务T2可以立即获得R行的共享锁,因为读取没有改变R的数据,称为锁兼容(Lock Compatible)
如果有他事务T3想获得R的排它锁,则其必须等待事务T1,T2释放R上的共享锁,称为所不兼容。
共享锁和排它锁的兼容性如下:
X与任何的锁都不兼容,而S与S兼容。
注意:S和X都是行锁,兼容是对同一记录(row)锁的兼容性情况。
若将上锁的对象看成一棵树,那么对最下层的对象上锁,也就是对最细粒度的对象上锁,那么首先需要对粗粒度的对象上锁。
如果需要对页上的记录R进行上X锁,那么分别需要对数据库A,表,页上意向锁IX,最后对记录R上X锁。若其中任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成。举例来说,在对记录R加X锁之前,已经有事务对表I进行了S表锁,那么表I上已经存在S锁,之后事务需要对记录R在表I上加IX,由于不兼容,所以该事务需要等待表锁操作完成。
InnoDB存储引擎支持意向锁设计比较简单,其意向锁即为表级别的锁。其设计目的主要为了在一个事务中揭晓下一行将被请求的锁类型,两种意向锁如下:
1》意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁
2》意向排它锁(IX Lock),事务想要获得一张表中某几行的排它锁
由于InnoDB存储引擎支持的是行级别的锁,因此意向锁其实不会阻塞除全表扫描以外的任何请求。故表级别的意向锁和行级别的锁的兼容性如下: