基于MySQL57学习之行级锁

行级锁介绍

MySQL的行级锁,是由存储引擎来实现的,看了下InnoDB的行级锁相关的视频,整理一下,算是笔记吧。

InnoDB行锁是通过给索引上的索引项加锁来实现的,因此InnoDB这种行锁实现特点意味着:只有通过索引条件检索的数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁

InnoDB的行级锁,按照锁定范围分为四种

记录锁(RecordLocks):锁定索引中一条记录。间隙锁(GapLocks):要么锁住索引记录中间的值,要么锁住第一个索引记录前面的值或者最后一个索引记录后面的值。临键锁(Next-KeyLocks):是索引记录上的记录锁和在索引记录之前的间隙锁的组合(间隙锁+记录锁)。插入意向锁(InsertIntentionLocks):做insert操作时添加的对记录id的锁。按照功能分为两种

共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。然后在我们进行UPDATE、DELETE和INSERT的时候,InnoDB会自动给涉及数据集加排他锁(X),

然后普通的SELECT语句,InnoDB不会加任何锁,但我们可以在select语句中自己加上锁。如:

SELECT*FROMtable_nameLOCKINSHAREMODE(共享锁)

SELECT*FROMtable_nameFORUPDATE(排他锁)

但是加完使用完之后一定要记得释放。

意向锁IntentionLocks

InnoDB引擎实现的表级锁,mysql内部使用,咱们用不到。它可以和行级锁共存。作用是为了时的性能提升。

例如:事务A修改user表的记录r,会给记录r上一把行级的排他锁(X),同时会给user表上一把意向排他锁(IX),这时事务B要给user表上一个表级的排他锁就会被阻塞。意向锁通过这种方式实现了行锁和表锁共存且满足事务隔离性的要求。

因为可以和行锁共存,所以有了意向共享锁(IS锁)和意向排他锁(IX锁)。

意向锁相互兼容,因为IX、IS只是表明申请更低层次级别元素(比如page、记录)的X、S操作。因为上了表级S锁后,不允许其他事务再加X锁,所以表级S锁和X、IX锁不兼容上了表级X锁后,会修改数据,所以表级X锁和IS、IX、S、X(即使是行排他锁,因为表级锁定的行肯定包括行级速订的行,所以表级X和IX、行级X)不兼容。上了行级X锁后,行级X锁不会因为有别的事务上了IX而堵塞,一个mysql是允许多个行级X锁同时存在的,只要他们不是针对相同的数据行。记录锁(RecordLocks)

仅仅锁住索引记录的一行,在单条索引记录上加锁。

记录锁锁住的是索引,不是记录本身,如果该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。

所以说当一条sql没有走任何索引时,那么将会在每一条聚合索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。

间隙锁(GapLocks)

间隙锁是区间锁,仅仅锁住一个索引区间(开区间,不包括双端端点)

间隙锁是在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身。

间隙锁可用于防止幻读,保证索引间的不会被插入数据。

临键锁(Next-KeyLocks)

林间锁,左开右闭区间,(1,9]这样。

默认情况下,innodb使用next-keylocks来锁定记录。如select…forupdate;但当查询的索引含有唯一属性的时候,Next-KeyLock会进行优化,将其降级为RecordLock,即仅锁住索引本身,不是范围。

Next-KeyLock在不同的场景中会退化:

行锁加锁规则

1)主键索引

1.等值查询

(1)命中记录,加记录锁。

(2)未命中记录,加间隙锁。

2.范围查询

(1)没有命中任何一条记录时,加间隙锁。

(2)命中1条或者多条,包含where条件的临键区间,加临键锁

2)辅助索引

1.等值查询

(1)命中记录,命中记录的辅助索引项+主键索引项加记录锁,辅助索引项两侧加间隙锁。

(2)未命中记录,加间隙锁

2.范围查询

(1)没有命中任何一条记录时,加间隙锁。

(2)命中1条或者多条,包含where条件的临键区间加临键锁。命中记录的id索引项加记录锁。

mysql视频教程数据库5.7从入门到精通零基础自学全套DBA在线课程淘宝¥19¥60购买


转载请注明:http://www.aierlanlan.com/rzgz/3657.html