lock与latch
在数据库中,lock与latch都可以成为锁,但两者有截然不同的含义。
latch 一般称为闩锁(轻量级的锁) 因为其要求锁定的时间非常短,若持续时间长,则应用性能非常差,在InnoDB存储引擎中,latch有可以分为mutex(互斥锁)和rwlock(读写锁)其目的用来保证并发线程操作临界资源的正确性,并且没有死锁检测的机制。
lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同),此外lock正如大多数数据库中一样,是有死锁机制的。
意向锁
将锁定的对象分为多个层次,意味着事务希望在更细粒度上进行加锁。
比如如果对一个数据对象加IS锁,表示它的子结点有意向加 S锁。例如,要对某个元组加 S锁,则要首先对关系和数据库加 IS锁。
数据库的层级结构如下:
由于InnoDB存储引擎支持的是行级别的锁,因此意向锁其实是不会阻塞除全表扫以外的任何请求。意向锁只是说明该事务有意向对子节点加某个锁。
意向锁与行级锁的兼容性如下:
作用
引进意向锁是为了提高封锁子系统的效率。该封锁子系统支持多种封锁粒度。原因是:在多粒度封锁方法中一个数据对象可能以两种方式加锁 ― 显式封锁和隐式封锁。因此系统在对某一数据对象加锁时不仅要检查该数据对象上有无(显式和隐式)封锁与之冲突,还要检查其所有上级结点和所有下级结点,看申请的封锁是否与这些结点上的(显式和隐式)封锁冲突,显然,这样的检查方法效率很低。为此引进了意向锁。
一致性非锁定读
一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行正在执行DELETE或UPDATE操作,这是读取操作不会因此等待行上锁的释放。相反的,InnoDB会去读取行的一个快照数据。
上面展示了InnoDB存储引擎一致性的非锁定读。之所以称为非锁定读,因为不需要等待访问的行上X锁的释放。
但是在不同的事务隔离级别下,读取的方式不同,并不是每个事务隔离级别下都是采用非锁定的一致性读,此外,即使使用非锁定的一致性读,但是对于快照数据的定义也各不相同。
在事务隔离级别RC和RR下,InnoDB存储引擎引擎使用非锁定的一致性读。然而,对于快照数据的定义却不相同。在RC事务隔离级别下,对于快照数据,非一致性读总是被锁定行的最新一份快照数据。而在RR事务隔离级别下,对于快照数据,非一致性读总是读取事务开始时的行数据版本。即:RC级别再其他事务提交之后即能看到数据的最新版本。RR级别总是读取事务开始时的行数据,即使其他事务提交了也是如此。(不做演示了)。
锁的算法
行锁的三种算法
Reord Lock:单行记录上的锁
Gap Lock:间隙锁,锁定一个范围,但是不包含记录本身
Next-Key Lock:Gap Lock + Reord Lock,锁定一个范围,并且锁定记录本身
Next-Key Lock是结合Gap Lock和Record Lockd 一种锁定算法,在Nex-Key Lock算法下,InnoDB对于行的查询都是采用这种锁定算法,例如一个索引有10 11 13 20这四个值,那么该索引可能被Next-Key Locking的区间为:
(-∞,10]
(10,11]
(11,