gap lock/next-key lock浅析Basic-Paxos协议日志同步应用
http://www.cnblogs.com/renolei/p/4673842.html
当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将锁细分为如下几种子类型:
record lock (RK)
记录锁, 仅仅锁住索引记录的一行
gap lock (GK)
区间锁, 仅仅锁住一个区间(开区间)
insert intention lock (IK)
意向插入锁
next key lock (NK)
record lock + gap lock, 半开半闭区间, 且下界开, 上界闭
以下锁兼容矩阵:
request与granted之间的兼容矩阵:
| Type of active |
Request | lock (granted) |
lock | RK GK IK NK |
---------+-----------------+
RK | 0 1 1 0 |
GK | 1 1 1 1 |
IK | 1 0 1 0 |
NK | 0 1 1 0 |
下面构造集中场景简单描述下record lock/gap lock/next-key lock
Table schema
CREATE TABLE `reno` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8构造数据
insert into reno select 5, 'aa';
insert into reno select 7, 'bb';
insert into reno select 9, 'cc';
insert into reno select 18, 'dd';
insert into reno select 23, 'ee';
insert into reno select 30, 'ff';
insert into reno select 40, 'gg';
insert into reno select 45, 'hh';
insert into reno select 99, 'ii';查看结果
select * from reno;
+----+------+
| id | name |
+----+------+
| 5 | aa |
| 7 | bb |
| 9 | cc |
| 18 | dd |
| 23 | ee |
| 30 | ff |
| 40 | gg |
| 45 | hh |
| 99 | ii |
+----+------+
9 rows in set (0.00 sec)查看tx_isolation
SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
+-----------------------+----------------+
| @@GLOBAL.tx_isolation | @@tx_isolation |
+-----------------------+----------------+
| READ-COMMITTED | READ-COMMITTED |
+-----------------------+----------------+
1 row in set (0.00 sec)next-key lock只有在repeatable-read级别下才有意义, 防止出现幻读
设置tx_isolation级别为REPEATABLE-READ级别:
SET @@GLOBAL.tx_isolation = 'REPEATABLE-READ';
Query OK, 0 rows affected (0.00 sec) SET @@SESSION.tx_isolation = 'REPEATABLE-READ';
Query OK, 0 rows affected (0.00 sec) SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@GLOBAL.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)
case 1:
sesion 1 sesion 2 sesion 2 insert status start transaction; select * from reno where id = 9 for update; start transaction; insert into reno select 8,'jj'; ok insert into reno select 10,'kk'; ok insert into reno select 3,'ll'; ok insert into reno select 111,'mm'; ok rollback rollback - 加record lock, id = 9
case 2:
sesion 1 sesion 2 sesion 2 insert status start transaction; select * from reno where id = 15 for update; start transaction; insert into reno select 8, 'jj'; ok insert into reno select 10, 'kk'; block insert into reno select 16, 'll'; block insert into reno select 19, 'mm'; ok rollback rollback 加next-key lock, (9, 18]
innodb lock info:
------------
TRANSACTIONS
------------
Trx id counter 2990040255
Purge done for trx's n:o < 2990040253 undo n:o < 0 state: running but idle
History list length 323
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 38753, OS thread handle 0x7f377c68f700, query id 140937 localhost root init
show engine innodb status
---TRANSACTION 0, not started
MySQL thread id 9, OS thread handle 0x7f370817d700, query id 140906 127.0.0.1 root cleaning up
---TRANSACTION 2990040254, ACTIVE 8 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 38773, OS thread handle 0x7f377c60e700, query id 140924 localhost root executing
insert into reno select 10, 'kk'
------- TRX HAS BEEN WAITING 8 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 64257 page no 3 n bits 80 index `PRIMARY` of table `test`.`reno` trx id 2990040254 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 80000012; asc ;;
1: len 6; hex 0000b238648b; asc 8d ;;
2: len 7; hex d70001c00c0110; asc ;;
3: len 2; hex 6464; asc dd;; ------------------
---TRANSACTION 2990040253, ACTIVE 17 sec
2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 38758, OS thread handle 0x7f370807b700, query id 140919 localhost root cleaning up从上面的trx lock信息里看到此时等待的锁是: lock_mode X locks gap before rec
case 3:
sesion 1 sesion 2 sesion 2 insert status start transaction; select * from reno where id = 200 for update; start transaction; insert into reno select 1, 'jj'; ok insert into reno select 88, 'kk'; ok insert into reno select 100, 'll'; block insert into reno select 500, 'mm'; block rollback rollback 加next-key lock, (99, ~)
innodb lock info:
------------
TRANSACTIONS
------------
Trx id counter 2990040257
Purge done for trx's n:o < 2990040253 undo n:o < 0 state: running but idle
History list length 323
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 38753, OS thread handle 0x7f377c68f700, query id 141561 localhost root init
show engine innodb status
---TRANSACTION 0, not started
MySQL thread id 9, OS thread handle 0x7f370817d700, query id 141535 127.0.0.1 root cleaning up
---TRANSACTION 2990040256, ACTIVE 137 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 2 row lock(s)
MySQL thread id 38773, OS thread handle 0x7f377c60e700, query id 141548 localhost root executing
insert into reno select 500, 'kk'
------- TRX HAS BEEN WAITING 10 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 64257 page no 3 n bits 80 index `PRIMARY` of table `test`.`reno` trx id 2990040256 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;; ------------------
---TRANSACTION 2990040255, ACTIVE 153 sec
2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 38758, OS thread handle 0x7f370807b700, query id 141432 localhost root cleaning up从上面的trx lock信息里看到此时等待的锁是: lock_mode X insert intention waiting
简单总结下:
- 在case 1中, 实际上加的next-key lock是(9,9], 也就是id=9这一条记录被lock住, 其他所有的插入都没有关系.
- 在case 2中, 因为id=15记录不存在, 且记录中上下两个边界是id=9, id=18, 因此加的next-key lock是(9, 18], 在这个区间内插入的数据都会被block, 此区间外的数据写入则不受影响.
- 在case 3中, id=200的记录不存在, 并且比表中所有的记录都大, 因此innodb则认为next-key lock是(99, ~), 任何大于99的id记录插入都会被block, 小于99的id记录写入则不受影响.
next-key lock是为防止幻读的发生,而只有REPEATABLE-READ以及以上隔离级别才能防止幻读, 所以在READ-COMMITTED隔离级别下面没有next-key lock这一说法.
参考:
gap lock/next-key lock浅析Basic-Paxos协议日志同步应用的更多相关文章
- gap lock/next-key lock浅析 Basic-Paxos协议日志同步应用
http://www.cnblogs.com/renolei/p/4673842.html 当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将 ...
- 理解分布式一致性:Paxos协议之Basic Paxos
理解分布式一致性:Paxos协议之Basic Paxos 角色 Proposal Number & Agreed Value Basic Paxos Basic Paxos without f ...
- paxos协议更新日志
基于Paxos协议的数据同步与传统主备方式最大的区别在与Paxos只需任意超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失. Basic paxos协议更新日志 我们将数据持久 ...
- 理解分布式一致性:Paxos协议之Multi-Paxos
理解分布式一致性:Paxos协议之Multi-Paxos Multi-Paxos without failures Multi-Paxos when phase 1 can be skipped Mu ...
- Key lock 的秘密
研究死锁,或者观察sp_lock,有时候最恼人的莫过于你看到下面研究成果的key lock,但是却不知道究竟是哪个page 哪个row被lock住了: Exec sp_lock: 就说上面的key ...
- InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
InnoDB锁机制之Gap Lock.Next-Key Lock.Record Lock解析 有意思,解释的很好
- basic paxos解析
basic paxos是我见过最难懂的算法,我最近一个月都在研究这个东西,自认有一些粗浅的心得,在这里写一下我对它的理解 为了降低理解难度,本文使用了大量的比喻,可能词不达意,见谅 basic pax ...
- mysql 有报错 ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists
sh-4.1# /etc/init.d/mysqld status ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql ...
- Centos安装完MariaDB后启动不了 MySQL is not running, but lock file (/var/lock/subsys/mysql) exists
[root@admin-node subsys]# service mysql startStarting MySQL. ERROR! [root@admin-node subsys]# servic ...
随机推荐
- thinkphp结合云之讯做短信验证码
thinkphp结合云之讯做短信验证码先去云之讯注册账号 网址http://www.ucpaas.com/ 注册云之讯平台账号,即可免费获得10元测试费用测试够用啦 解压附件到 ThinkPHP\Li ...
- 9.2NOIP模拟题
9.2 NOIP模拟 题目名称 “与” 小象涂色 行动!行动! 输入文件 and.in elephant.in move.in 输出文件 and.out elephant.in move.in 时间限 ...
- 使用 typescript 开发 Vue
基础配置: 1. 准备一个使用 vue-cli 生成的项目 2. 使用 npm 一建安装基础配置 npm i -S @types/node typescript vue-class-component ...
- Dockerfile镜像的制作
Dockerfile镜像的制作 如果学习Docker,那么制作镜像这一步肯定不能少的,别人给你的是环境,而你自己做的才是你最终需要的东西,接下来就记录一下如何制作一个满足自己的镜像,我们使用docke ...
- NS2学习笔记(二)
Tcl语言 变量和变量赋值 set a "Hello World!" #将字符串赋值给变量a puts "NS2 say $a" #输出字符串的内容,其中$a表 ...
- Django 内容回顾
模板 变量 {{ }} 标签 {% %} if elif else for empty forloop() with...as csrf_token 过滤器 default length add da ...
- 【转】linux read 用法
转自:http://www.cnblogs.com/iloveyoucc/archive/2012/04/16/2451328.html 1.基本读取 read命令接收标准输入(键盘)的输入,或其他文 ...
- SQL Sever语言 存储过程及触发器
存储过程:就像函数一样的会保存在数据库中-->可编程性-->存储过程 创建存储过程: 保存在数据库表,可编程性,存储过程create proc jiafa --需要的参数@a int,@b ...
- Unity学习-软件的基本操作(二)
基本操作 1:Scene中 以小手显示,平移画布,与鼠标中键一样 2:平移 游戏对象,组件的 Position属性 也可设置 3:旋转 游戏对象,组件的 Rotation属性 也可设置 4:缩放 游戏 ...
- Android RecyclerView遇到notifyDataSetChanged无效时的解决方案
一.简述 不管AbsListView(ListView.GridView)或是新出的RecyclerView,在使用notifyDataSetChanged方法更新列表数据时,一定要保证数据为同个对象 ...