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这一说法.

参考:

Love truth but pardon errors

gap lock/next-key lock浅析 Basic-Paxos协议日志同步应用的更多相关文章

  1. gap lock/next-key lock浅析Basic-Paxos协议日志同步应用

    http://www.cnblogs.com/renolei/p/4673842.html 当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将 ...

  2. 理解分布式一致性:Paxos协议之Basic Paxos

    理解分布式一致性:Paxos协议之Basic Paxos 角色 Proposal Number & Agreed Value Basic Paxos Basic Paxos without f ...

  3. paxos协议更新日志

    基于Paxos协议的数据同步与传统主备方式最大的区别在与Paxos只需任意超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失. Basic paxos协议更新日志 我们将数据持久 ...

  4. 理解分布式一致性:Paxos协议之Multi-Paxos

    理解分布式一致性:Paxos协议之Multi-Paxos Multi-Paxos without failures Multi-Paxos when phase 1 can be skipped Mu ...

  5. Key lock 的秘密

    研究死锁,或者观察sp_lock,有时候最恼人的莫过于你看到下面研究成果的key lock,但是却不知道究竟是哪个page 哪个row被lock住了: Exec sp_lock:   就说上面的key ...

  6. InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

    InnoDB锁机制之Gap Lock.Next-Key Lock.Record Lock解析 有意思,解释的很好

  7. basic paxos解析

    basic paxos是我见过最难懂的算法,我最近一个月都在研究这个东西,自认有一些粗浅的心得,在这里写一下我对它的理解 为了降低理解难度,本文使用了大量的比喻,可能词不达意,见谅 basic pax ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. Unity 图形学 基础知识总结

    1. 渲染流水线     三大块:应用阶段,几何阶段,光栅化阶段                       渲染图元   顶点信息    GPU流水线     顶点数据=>     顶点着色器 ...

  2. 解决微信H5页面软键盘弹起后页面下方留白的问题(iOS端)

    前言:微信H5项目,ios端出现了软键盘输完隐藏后页面不会回弹,下方会有一大块留白 最近微信和ios都有版本升级,不知道是哪边升级造成的,但是经过测试,软键盘收起后,再滚动一下页面,下面的留白就会消失 ...

  3. 分享一些对IT人员非常好用的资源

    前言 分享一下本人工作至今整理的一些好用的资源,这些资源主要是一些工作和生活中用到的文档.软件和网站. 文档主要是面试相关的文档和技术文档,其中面试文档主要是Java这块的,技术文档就有很多,除了Ja ...

  4. Codeforces 769C

    很久没有发题解,今天这题卡了下百度没看到相关题解,最后还是看了官方题解才找到原本思路的bug过的. 题意:给出一个二维迷宫,*表示墙,. 表示路,X表示起点,问一个长度为k的路径,从X出发并且回到X, ...

  5. [ POI 2011 ] Party

    \(\\\) \(Description\) 给定一张 \(N\ (\ N\equiv 0\pmod{3}\ )\) 个节点,,\(M\)条边的图,并且保证该图存在一个大小至少为\(\frac{2}{ ...

  6. CSS基础知识(定位、浮动)

    12.浮动 特点:将当前元素脱离文档流    float: left 即左浮动  float: right 即右浮动 注:*父与子元素,设置子元素浮动不能超出父元素的范围 *多个元素均设置为浮动时,将 ...

  7. no斜体 背景图片坐标

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. Python3之Zip

    from collections import defaultdict from collections import OrderedDict d = defaultdict(list) d['a'] ...

  9. html5——2D转换

    transform 属性 1.向元素应用 2D 或 3D 转换 2.该属性允许我们对元素进行旋转.缩放.移动或倾斜. 缩放与位移 transform: scale(, 0.5);//水平缩放,垂直缩放 ...

  10. C# 返回值为 list<T>

    public List<T> test<T>(List<T> EntityList) where T : class { return EntityList; }