MySQL锁机制
1、什么是锁
锁是数据库区别于文件系统的一个关键特性,用于管理对共享资源的并发访问。
操作缓冲池中的LRU列表,删除、添加、移动LRU列表中的元素,为了保证一致性,必须有锁的介入。数据库系统用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。
2、lock与latch
latch一般称为闩锁(轻量级锁),因为其要求锁定的是时间必须非常短。若持续的时间长,则应用的性能会非常差。在innodb存储引擎中,latch又可以分为mutex(互斥量)和rwlock(读写锁)。目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。
lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。lock也是有死锁机制的。 lock与latch比较:
3、Innodb中的锁
1、锁的类型
innodb引擎实现了如下两种标准的行级锁:
1、共享锁(S lock),允许事务读一行数据
2、排它锁(X lock),允许事务删除或更新一行数据。
如果一个事务T1获得行r的共享锁,事务T2可以立即获得行r的共享锁,因为读取并没有改变行人的数据,称为这种情况为锁兼容。若其他的事务T3想获得行r的排它锁,则必须等待事务T1、T2释放行r上的共享锁。这种情况称为锁不兼容。
排它锁和兼容锁的兼容性:
排它锁(X)与任何锁都是不兼容的,共享锁(S)只与共享锁是兼容的。S和X都是行锁,兼容是指对同一记录(row)锁的兼容性情况。
innodb存储引擎支持多粒度(granular)锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在。innodb支持一种额外的锁方式,来支持不同粒度上进行加锁操作,称为意向锁(intention lock)。意向锁是将锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度上进行加锁。
若将上锁的对象看成一颗树,那么对最下层的对象上锁,也就是对最细粒度的对象进行上锁,那么首先需要对粗粒度的对象上锁。如果需要对页上的记录r进行上X锁,那么分别需要对数据库A、表、页上意向锁IX,最后对记录r上X锁。若其中任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成。举例:在对记录r加X锁之前,如果已经有事务对表1进行了S表锁,此时表1上已存在S锁,再有其他事务需要对记录r在表1上加上IX,由于X和S不兼容,该事务需要等待表1表锁释放之后,才能在记录r上加锁。
innodb存储引擎支持意向锁设计比较简练,其意向锁即为表级别的锁。支持两种意向锁:1、意向共享锁(IS lock),事务想要获得一张表中某几行的共享锁2、意向排它锁(IX lock),事务想要获得一张表中某几行的排它锁
由于innodb存储引擎支持的是行级别的锁,因此意向锁起始不会阻塞除全表扫以外的任何请求。
锁的兼容性:
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;查看innodb_trx结构信息: