Innodb 存储引擎 学习笔记 -锁(一)

锁的算法

innodb 3种行锁的算法:

1.Record Lock:  单个行记录上锁。

2.Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。

3.Net-Key Lock:Record Lock+Gap Lock,锁定一个范围,并且锁定记录本身。

例如,一个索引有10,11,13,20四个值,那么所有可能被Net-Key Lock的区间为:

(-inf,10]

(10,11]

(11,13]

(13,20]

(20,inf)

 

默认情况下(隔离级别为Repeatable read),innodb对行的查询都用到时Net-Key Lock算法:

当查询的列是唯一索引时,innodb会对Net-Key Lock进行优化,降级为Record Lock.

看一个例子:

先创建一张表,并插入3行数据

mysql> create table t(
    -> a int primary key);
Query OK, 0 rows affected (0.08 sec)

mysql> insert into t select 1;
Query OK, 1 row affected (0.08 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into t select 2;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into t select 3;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

建立两个会话A和B:

时间会话A会话B
1begin; 
2 select * from t where a = 3 for update;
+---+
| a |
+---+
| 3 |
+---+
1 row in set (0.00 sec)
 
3 begin;
4 

 insert into t select 4;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

 

commit;
Query OK, 0 rows affected (0.06 sec)

5commit;
Query OK, 0 rows affected (0.00 sec)
 

会话A对a=3进行了X锁定,并且a是主键且唯一

因此锁定的只是a=3这个值,而不是(2,3)这个范围,

所以在会话B插入a=4时,并不会阻塞。

 

当查询的列是辅助索引时,

对于聚集索引(主键) ,加Record Lock

对于辅助索引 ,Next-Key-Locking,

并对下一个键值加上gap lock

看个例子:

mysql> create table z(
    -> a int,
    -> b int,
    -> primary key(a),
    -> key(b)
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> insert into z select 1,1;
Query OK, 1 row affected (0.11 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into z select 3,1;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into z select 5,3;
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into z select 7,6;
Query OK, 1 row affected (0.08 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into z select 10,8;
Query OK, 1 row affected (0.08 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from z;
+----+------+
| a  | b    |
+----+------+
|  1 |    1 |
|  3 |    1 |
|  5 |    3 |
|  7 |    6 |
| 10 |    8 |
+----+------+
时间会话A会话B
1

 begin;

 

 
2

select * from z where b=3 for update;
+---+------+
| a | b    |
+---+------+
| 5 |    3 |
+---+------+
1 row in set (0.00 sec)

 

#对辅助索引b进行查询,使用Next-Key-Locking对b=3进行加锁。有两个索引,所以分别加锁。

对于聚集索引 ,a=5加Record Lock

对于辅助索引 ,b=3加Next-Key-Locking,锁定范围【1,3】,

并对下一个键值加上gap lock,即范围为(3,6)的锁

 
3 begin;
  

mysql> insert into z select 9,1;

 

# b=1在【1,3】范围内,因此被阻塞

4 

mysql> insert into z select 23,2;

 

# b=2在【1,3】范围内,因此被阻塞

5 

mysql> insert into z select 6,5;

 

# b=2在(3,6)范围内,因此被阻塞

6 

mysql> insert into z select 6,7;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

 

#b=7不在锁定范围,因此不会被阻塞

7commit; 
8 commit;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值