快速入门MySQL8.0锁


Shared and Exclusive Locks: 行锁

  • S锁为共享锁,读锁,允许持有锁的事务读取row
  • X锁为排它锁, 写锁,允许持有锁的事务update或者delete行

如果一个事务t1在行r上持有S锁,那么另外一个事务t2对r上加锁的请求:S锁,✅,那么t1和t2同时持有r上的S锁;但是如果t2请求的是X锁,会被拒绝,❌
如果一个事务t1在行r上持有X锁, 那么另外一个事务t2对r上加锁的请求,无论是S锁还是X锁,都会被拒绝 ❌

Intention Locks: 意向锁: 表锁

InnoDB 支持多粒度锁(multiple granularity locking),它允许行级锁与表级锁共存,而意向锁就是其中的一种表锁。

  • IS: 表示事务打算在表的某些行上设置S锁;例如:SELECT … FOR SHARE sets an IS lock
  • IX: 表示事务打算在表的某些行上设置X锁;例如:SELECT … FOR UPDATE sets an IX lock.

意向锁是由数据引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁: 加X锁需要先加IX锁,加S锁要加IS或IX(an IS lock or stronger on the table)

表级别锁的兼容性:

意向锁之间互相兼容:但除了 IS 与 S 兼容外,意向锁会与 共享锁 / 排他锁 互斥 。(意向锁不会与行级的共享 / 排他锁互斥!!!)

IS意向锁IX意向锁
共享锁(S)兼容互斥
排它锁(X)互斥互斥

Record Locks(记录锁)

记录锁是对索引记录的锁。即使一个表里面没有定义索引,InnoDB还可以使用隐藏聚集索引进行记录锁定。

For example, SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; prevents any other transaction from inserting, updating, or deleting rows where the value of t.c1 is 10.

GAP Locks (间隙锁)

间隙锁是对索引记录之间的间隙的锁(不锁索引),或者是对第一个索引记录之前或最后一个索引记录之后的间隙的锁。

例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;阻止其他事务将 的值插入15到列中t.c1,无论列 中是否已经存在任何此类值,因为该范围内所有现有值之间的间隙被锁定。

间隙锁是性能和并发性之间权衡的一部分,只用于部分事务隔离级别;RC的隔离级别,搜索和索引扫描是禁用gap lock的,只能用于外键约束和重复键约束;
间隙锁没有X和S的区别(他俩的功能一样),间隙锁可以共存;它们的唯一目的是防止其他事务插入间隙。

允许冲突间隙锁的原因是,如果从索引中清除记录,则必须合并不同事务在记录上持有的间隙锁。

Next-Key Locks

next-key 锁是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合
InnoDB执行行级锁定的方式是,当它搜索或扫描表索引时,它会在遇到的索引记录上设置共享锁或排他锁。因此,行级锁实际上是索引记录锁。不仅锁定一个记录上的索引,也锁定索引之间的间隙。例如一个索引包含以下值:10, 11, 13, and 20,那么就需要锁定以下区间:

(-, 10]
(10, 11]
(11, 13]
(13, 20]
(20, +)

InnoDB默认采用RR的隔离级别,并且使用next-key lock来进行搜索和索引扫描,以防止幻读。

Insert Intention Locks: 插入意向锁

插入意向锁,是有insert操作设置的在插入行之前的间隙锁;如果多个事务要在同样的索引间隙间插入,但是他们的插入位置不同,则不会互相阻塞。
例如:假设存在值为 4 和 7 的索引记录。 两个独立的事务分别尝试插入值 5 和 6 ,在获得插入行的排他锁之前,每个事务都使用插入意向锁锁定 4 和 7 之间的间隙,但不会相互阻塞,因为行是不冲突的。
Client A creates a table containing two index records (90 and 102) and then starts a transaction that places an exclusive lock on index records with an ID greater than 100. The exclusive lock includes a gap lock before record 102:
对 ID 大于 100 的索引记录放置排他锁。 排他锁包括记录 102 之前的间隙锁

mysql> CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
mysql> INSERT INTO child (id) values (90),(102);

mysql> START TRANSACTION;
mysql> SELECT * FROM child WHERE id > 100 FOR UPDATE;
+-----+
| id  |
+-----+
| 102 |
+-----+

Client B begins a transaction to insert a record into the gap. The transaction takes an insert intention lock while it waits to obtain an exclusive lock.
事务在等待获得排他锁时使用插入意向锁

mysql> START TRANSACTION;
mysql> INSERT INTO child (id) VALUES (101);

AUTO-INC Locks

AUTO-INC 锁是一个特殊的表锁,是在事务插入AUTO_INCREMENT 列的时候使用的。最简单的情况下,如果一个事务正在插入表,其他事务的插入必须等待,以便第一个事务插入的行接收连续的主键值。

Predicate Locks for Spatial Indexes 空间索引谓词锁

InnoDB支持SPATIAL对包含空间数据的列进行索引。如果操作中包含 SPATIAL索引加锁的时候,next-key lock不能很好支持RR和串行化隔离级别;

多维数据中没有绝对排序的概念,所以不清楚哪个是 “ next ”键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值