INNODB 锁 概述

在information_schema中有这么一个表:innnodb_locks

该表存储innodb事务中,已经发出请求但还尚未获得数据的每一个锁的信息。事务持有的每一个锁都可能阻塞另一个事务。

字段释义如下:

lock_id:唯一锁ID编号,可视为一个复杂字符串;尽管锁ID中包含当前事务ID号,但锁ID中的数据格式随时都有变化
lock_trx_id:持有该锁的事务ID,可与innodb_trx表的trx_id列关联查看事务详细信息。
lock_mode:锁类型,允许的值有:S,X,IS,IX,AUTO_INC,UNKNOW
lock_type:锁类型,RECORD表示行级锁,TABLE表示表级锁
lock_table:被锁定或存在行级锁的表名
lock_index:如果是行级锁,则显示锁定记录的索引名;否则为空
lock_space:如果是行级锁,则显示锁定记录的表空间ID;否则为空
lock_page:如果是行级锁,则显示锁定记录的page number;否则为空
lock_rec:如果是行级锁,则显示锁定记录的Heap number;否则为空
lock_data:与锁相关的数据信息。



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
INNODB锁
1.共享锁和排它锁:Share Lock和Exclusive Lock.
 

     

 

2.意向锁:
INNODB支持多粒度的锁,即行级锁和表级锁。当一个事务需要对某个表的所有行进行update操作(写锁锁表)之前,它需要进行如下步骤:
a).判断该表是否被其它事务用表级锁锁定
b).判断该表中的某些行是否被行级锁锁定
c).如果在上面两步中都没有行被锁定,那么事务可以锁定此表。
注意:在步骤b)时,要判断表中是否有行被锁定需要遍历整个表,效率实在不高。于是有了意向锁。意向锁是表级锁。它的存在是 为了判断表上是否存在对应类型的行锁。因此只有对行做操作的时候,才会申请意向锁。

存在意向锁后,对表的任何加锁操作都需要先加意向锁。因此上述步骤可以改为如下:
a).不变。
b). 判断该表是否存在其它事务的意向锁。(如果有意向锁,说明表中有某些行被锁住了,因此申请的写锁会被阻塞)
c).如果上面两步都没有检测到锁,那么给表加写锁。

锁类型兼容性矩阵如下: 兼容-->+;不兼容-->-

      

3.Record Locks(记录锁)
记录锁是锁定索引行的锁。
比如:select c1 from t where c1=10; 它会锁定c1值为10的所有行;此时你不能对这些行上进行insert,update,delete等操作
记录锁总是锁定索引记录。如果一个表没有定义索引,innodb会自动创建隐藏的聚簇索引,然后用这个索引来进行锁定。

4.Gap Locks(间隙锁)
GAP锁的出现是为了解决幻读问题。GAP锁是加在两条记录之间,或者第一个记录之前的间隙,最后一个记录之后的间隙。从而阻止其他事务在这些位置插入新的记录,并提交。它的作用也仅是如此;两个不同的事务是可以对同一个间隙同时加GAP锁的,它们不会产生锁冲突。
由于GAP锁的目的是为了防止同一事务的两次当前读出现幻读情况。因此,对于使用唯一索引(唯一键索引或主键索引)来搜索唯一行的语句,不需要加GAP锁。
GAP锁是可以显示地禁用的。有两种方法,1、设置事务隔离等级为RC。2、启用系统变量:innodb_locks_unsafe_for_binlog
更多详细信息可以看:
  a).http://hedengcheng.com/?p=771#_组合三:id非唯一索引+RC
  b).https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-gap-locks

5.Next-key Locks
Next-Key Locks是Record Locks 和Gap Locks的结合,但在GAP锁上有一点小差异,就是Next-key锁只会锁满足条件的记录的前面的间隙。
6.Insert Intention Locks
插入意向锁:
首先、它是GAP锁中的一种类型,它是被行插入之前的插入操作产生的。
其二、它表示,如果多事务同时插入数据到同一个索引间隙,只要插入不是该间隙内的同一个位置的话,他们之间不需要互相等待。
7.AUTO-INC Locks:
AUTO-INC锁是一种特殊的表级锁。表中有AUTO_INCRMENT列的时候,一个事务向该表中插入时会出现此类锁。
对自增列来说,insert操作可以分为三类;
1.简单INSERT;能预先预测插入的行数的。
2:Bulk Insert;不能事先预测行数。比如:insert...select...;replace...select...;load data 等
3:mixed模式插入;
它包括在一些简单insert中,自增的列指定了一些值,一些没指定,eg.
insert into t(c1,c2) values(1,'a'),(NULL,'b'),(5,'c'),(NULL,'D');
还包括如下:
insert ... on duplicate key update

AUTO-INC锁的模式可由参数innodb_autoinc_lock_mode配置,该参数允许的值有0,1,2三个;默认值是1。
0----->传统(traditional)模式;5.1版本之前的模式,为了向下兼容。在这个模式下,所有的insert类操作都会产生一个特殊的表级锁。锁的存活时间是从在插入的这个过程中(从insert开始到insert结束),而不是整个事务过程。这是为了确保在一个给定的INSERT语句序列中,分配的自动增量值是连续的。在主从复制或使用二进制日志做恢复的场景中且日志格式为statement-based时,此参数设为0和1均是安全的。然后表锁会限制并发性和扩展性。
1---->连续(consecutive)模式。该模式下,能预测插入行数的简单insert语句不会产生表级锁;而是在一个互斥锁的控制下获得所需的自动增量值的数量。而这个互斥锁只在分配的过程中存在,而不等整个insert语句完成。 批量插入依然会产生表锁,并且在insert执行的过程中表锁一直存在;这样可以保证insert操作产生的自增值是连续的,安全的。
2---->交叉(interleaved)模式;该模式下,insert类语句均不会产生表级锁 ,多个语句可以在同一个时间点同时执行;自增值可以保证是唯一且单调递增的,但同一个insert语句的自增值不一定是连续的。是最快速和最具扩展性的模式;但当使用statement-based的日志格式时,不安全。

8.Predicate Locks for Spatial Indexes

posted @ 2017-07-17 17:39  ERIC_DANIELS  阅读(181)  评论(0)    收藏  举报