MySQL锁系列(七)之 锁算法详解

阅读原文请点击: http://click.aliyun.com/m/23854/
摘要: 能学到什么 隔离级别和锁的关系 重点讲解在RR隔离级别下的加锁算法逻辑 重点罗列了比较典型的几种加锁逻辑案例 对insert的加锁逻辑进行了深度剖析 实战中剖析加锁的全过程 InnoDB为什么要这样加锁 隔离级别和算法 repeatable-read 1.

能学到什么
隔离级别和锁的关系
重点讲解在RR隔离级别下的加锁算法逻辑
重点罗列了比较典型的几种加锁逻辑案例
对insert的加锁逻辑进行了深度剖析
实战中剖析加锁的全过程
InnoDB为什么要这样加锁
隔离级别和算法
repeatable-read
1. 使用的是next-key locking
2. next-key lock  =  record lock + Gap lock

read-committed
1. 使用的是 record lock
2. 当然特殊情况下( purge + unique key ),也会有Gap lock
我们接下来就以RR隔离级别来阐述,因为RC更加简单

锁的通用算法
RR隔离级别
1. 锁是在索引上实现的
2. 假设有一个key,有5条记录, 1,3,5,7,9.  如果where id<5 , 那么锁住的区间不是(-∞,5),而是(-∞,1],(1,3],(3,5] 多个区间组合而成
3. RR隔离级别使用的是:next-key lock算法,即:锁住 记录本身+区间
4. next-key lock 降级为 record lock的情况
    如果是唯一索引,且查询条件得到的结果集是1条记录(等值,而不是范围),那么会降级为记录锁
    典型的案例:where primary_key = 1 (会降级), 而不是 where primary_key < 10 (由于返回的结果集不仅仅一条,那么不会降级)
5. 上锁,不仅仅对主键索引加锁,还需要对辅助索引加锁,这一点非常重要
锁算法的案例剖析
RR隔离级别
表结构
dba:lc_3> show create table a;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------+
| Table | Create Table
             |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------+
| a     | CREATE TABLE `a` (
  `a` int(11) NOT NULL,
  `b` int(11) DEFAULT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`a`),
  UNIQUE KEY `idx_b` (`b`),
  KEY `idx_c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------+
1 row in set (0.00 sec)


dba:lc_3> select * from a;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 1 |    3 |    5 |    7 |
| 3 |    5 |    7 |    9 |
| 5 |    7 |    9 |   11 |
| 7 |    9 |   11 |   13 |
+---+------+------+------+
4 rows in set (0.00 sec)

* 设置RR隔离级别
set tx_isolation = 'repeatable-read';
等值查询,非唯一索引的加锁逻辑
dba:lc_3> begin;
Query OK, 0 rows affected (0.00 sec)

dba:lc_3> select * from a where c=9 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 5 |    7 |    9 |   11 |
+---+------+------+------+
1 row in set (0.00 sec)

TABLE LOCK table `lc_3`.`a` trx id 133601815 lock mode IX
RECORD LOCKS space id 281 page no 5 n bits 72 index idx_c of table `lc_3`.`a` trx id 133601815 lock_mode X
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc     ;;
1: len 4; hex 80000005; asc     ;;

RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133601815 lock_mode X locks rec but not gap
Record lock, heap no 4 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000005; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d012a; asc    '  *;;
3: len 4; hex 80000007; asc     ;;
4: len 4; hex 80000009; asc     ;;
5: len 4; hex 8000000b; asc     ;;

RECORD LOCKS space id 281 page no 5 n bits 72 index idx_c of table `lc_3`.`a` trx id 133601815 lock_mode X locks gap before rec
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 8000000b; asc     ;;
1: len 4; hex 80000007; asc     ;;


锁的结构如下:

对二级索引idx_c:
    1. 加next-key lock,((7,3),(9,5)] , ((9,5),(11,7)],解读一下:((7,3),(9,5)] 表示:7是二级索引key,3是对应的主键
    2.这样写不太好懂,所以以后就暂时忽略掉主键这样写: next-key lock = (7,9],(9,11]

对主键索引primary: 加record lock,[5]


等值查询,唯一键的加锁逻辑
dba:lc_3> select * from a where b=9 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 7 |    9 |   11 |   13 |
+---+------+------+------+
1 row in set (0.00 sec)

TABLE LOCK table `lc_3`.`a` trx id 133601816 lock mode IX
RECORD LOCKS space id 281 page no 4 n bits 72 index idx_b of table `lc_3`.`a` trx id 133601816 lock_mode X locks rec but not gap
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc     ;;
1: len 4; hex 80000007; asc     ;;

RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133601816 lock_mode X locks rec but not gap
Record lock, heap no 5 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000007; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d0137; asc    '  7;;
3: len 4; hex 80000009; asc     ;;
4: len 4; hex 8000000b; asc     ;;
5: len 4; hex 8000000d; asc     ;;


锁的结构如下:

对二级索引idx_b:
    1. 加record lock,[9]

对主键索引primary:
    1. 加record lock,[7]


>= ,非唯一索引的加锁逻辑
dba:lc_3> select * from a where c>=9 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 5 |    7 |    9 |   11 |
| 7 |    9 |   11 |   13 |
+---+------+------+------+
2 rows in set (0.00 sec)

TABLE LOCK table `lc_3`.`a` trx id 133601817 lock mode IX
RECORD LOCKS space id 281 page no 5 n bits 72 index idx_c of table `lc_3`.`a` trx id 133601817 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc     ;;
1: len 4; hex 80000005; asc     ;;

Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 8000000b; asc     ;;
1: len 4; hex 80000007; asc     ;;

RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133601817 lock_mode X locks rec but not gap
Record lock, heap no 4 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000005; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d012a; asc    '  *;;
3: len 4; hex 80000007; asc     ;;
4: len 4; hex 80000009; asc     ;;
5: len 4; hex 8000000b; asc     ;;

Record lock, heap no 5 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000007; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d0137; asc    '  7;;
3: len 4; hex 80000009; asc     ;;
4: len 4; hex 8000000b; asc     ;;
5: len 4; hex 8000000d; asc     ;;

锁的结构如下:

对二级索引idx_c:
    1. 加next-key lock, (7,9],(9,11],(11,∞]

对主键索引primary:
    1. 加record lock,[5],[7]

>= ,唯一索引的加锁逻辑
dba:lc_3> select * from a where b>=7 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 5 |    7 |    9 |   11 |
| 7 |    9 |   11 |   13 |
+---+------+------+------+
2 rows in set (0.00 sec)


TABLE LOCK table `lc_3`.`a` trx id 133601820 lock mode IX
RECORD LOCKS space id 281 page no 4 n bits 72 index idx_b of table `lc_3`.`a` trx id 133601820 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000007; asc     ;;
1: len 4; hex 80000005; asc     ;;

Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc     ;;
1: len 4; hex 80000007; asc     ;;

RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133601820 lock_mode X locks rec but not gap
Record lock, heap no 4 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000005; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d012a; asc    '  *;;
3: len 4; hex 80000007; asc     ;;
4: len 4; hex 80000009; asc     ;;
5: len 4; hex 8000000b; asc     ;;

Record lock, heap no 5 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000007; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d0137; asc    '  7;;
3: len 4; hex 80000009; asc     ;;
4: len 4; hex 8000000b; asc     ;;
5: len 4; hex 8000000d; asc     ;;

锁的结构如下:

对二级索引idx_b:
    1. 加next-key lock, (5,7],(7,9],(9,∞]

对主键索引primary:
    1. 加record lock,[5],[7]


<= , 非唯一索引的加锁逻辑

dba:lc_3> select * from a where c<=7 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 1 |    3 |    5 |    7 |
| 3 |    5 |    7 |    9 |
+---+------+------+------+
2 rows in set (0.00 sec)

TABLE LOCK table `lc_3`.`a` trx id 133601822 lock mode IX
RECORD LOCKS space id 281 page no 5 n bits 72 index idx_c of table `lc_3`.`a` trx id 133601822 lock_mode X
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000005; asc     ;;
1: len 4; hex 80000001; asc     ;;

Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000007; asc     ;;
1: len 4; hex 80000003; asc     ;;

Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc     ;;
1: len 4; hex 80000005; asc     ;;

RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133601822 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000001; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d0110; asc    '   ;;
3: len 4; hex 80000003; asc     ;;
4: len 4; hex 80000005; asc     ;;
5: len 4; hex 80000007; asc     ;;

Record lock, heap no 3 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000003; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d011d; asc    '   ;;
3: len 4; hex 80000005; asc     ;;
4: len 4; hex 80000007; asc     ;;
5: len 4; hex 80000009; asc     ;;


锁的结构如下:

对二级索引idx_c:
    1. 加next-key lock, (-∞,5],(5,7],(7,9]

对主键索引primary:
    1. 加record lock,[1],[3]


<= , 唯一索引的加锁逻辑
dba:lc_3> select * from a where b<=5 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 1 |    3 |    5 |    7 |
| 3 |    5 |    7 |    9 |
+---+------+------+------+
2 rows in set (0.00 sec)



TABLE LOCK table `lc_3`.`a` trx id 133601823 lock mode IX
RECORD LOCKS space id 281 page no 4 n bits 72 index idx_b of table `lc_3`.`a` trx id 133601823 lock_mode X
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000003; asc     ;;
1: len 4; hex 80000001; asc     ;;

Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000005; asc     ;;
1: len 4; hex 80000003; asc     ;;

Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000007; asc     ;;
1: len 4; hex 80000005; asc     ;;

RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133601823 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000001; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d0110; asc    '   ;;
3: len 4; hex 80000003; asc     ;;
4: len 4; hex 80000005; asc     ;;
5: len 4; hex 80000007; asc     ;;

Record lock, heap no 3 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000003; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d011d; asc    '   ;;
3: len 4; hex 80000005; asc     ;;
4: len 4; hex 80000007; asc     ;;
5: len 4; hex 80000009; asc     ;;


锁的结构如下:

对二级索引idx_b:
    1. 加next-key lock, (-∞,3],(3,5],(5,7]

对主键索引primary:
    1. 加record lock,[1],[3]

> , 非唯一索引的加锁逻辑
dba:lc_3> select * from a where c>9 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 7 |    9 |   11 |   13 |
+---+------+------+------+
1 row in set (0.00 sec)



RECORD LOCKS space id 281 page no 5 n bits 72 index idx_c of table `lc_3`.`a` trx id 133601825 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 8000000b; asc     ;;
1: len 4; hex 80000007; asc     ;;

RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133601825 lock_mode X locks rec but not gap
Record lock, heap no 5 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 4; hex 80000007; asc     ;;
1: len 6; hex 000007f66444; asc     dD;;
2: len 7; hex fc0000271d0137; asc    '  7;;
3: len 4; hex 80000009; asc     ;;
4: len 4; hex 8000000b; asc     ;;
5: len 4; hex 8000000d; asc     ;;






锁的结构如下:

对二级索引idx_c:
    1. 加next-key lock, (9,11],(11,∞]

对主键索引primary:
    1. 加record lock,[7]


> , 唯一索引的加锁逻辑
dba:lc_3> select * from a where b>7 for update;
+---+------+------+------+
| a | b    | c    | d    |
+---+------+------+------+
| 7 |    9 |   11 |   13 |
+---+------+------+------+
1 row in set (0.00 sec)
阅读原文请点击: http://click.aliyun.com/m/23854/

猜你喜欢

转载自1369049491.iteye.com/blog/2380942