行锁的3中算法

Record Lock:单个行记录上的锁

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

Next-key Lock:Gap Lock+Record Lock锁定一个范围,并且锁定记录本身

Record Lock总是会去锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这是会使用隐式的主键来进行锁定

Next-Key Lock是结合Gap Lock和Record Lockd 一种锁定算法,在Nex-Key Lock算法下,InnoDB对于行的查询都是采用这种锁定算法,例如一个索引有10 11 13 20这四个值,那么该索引可能被Next-Key Locking的区间为:

看一下执行表的SQL语句

表t共有1 2 5 三个值,在会话A中首先对a=5进行了X锁定。而由于a是主键且唯一,因此锁定的仅是5这个值,而不是(2,5)这个范围,这样在会话B中插入4不会阻塞,可以立即插入并返回,及锁定由Next-Key Lock算法降级为了Record Lock,从而提高应用的并发性

正如前面介绍,Next-Key Lock 降级为Record Lock仅在查询的列是唯一索引的情况下,如果是辅助索引,有不同

>create table z(a INT,b INT, PRIMARY KEY(a),KEY(b));

>INSERT INTO z SELECT 1,1;

>INSERT INTO z SELECT 3,1;

>INSERT INTO z SELECT 5,3;

>INSERT INTO z SELECT 7,6;

>INSERT INTO z SELECT 10,8;

表z的列b是辅助索引,若在会话A中执行下面的SQL语句

>SELECT  * FROM z WHERE b=3 FRO UPDATE;

很明显,这是SQL语句通过索引b进行查询,因此使用传统的Next-Key Locking技术加锁,并且由于有两个索引,其需要分别进行锁定,对于聚集索引,其仅对列a等于5的索引加Record Lock,而对于辅助索引,其加上了Next-Key Lock,锁定的范围是(1,3)特别需要注意的是,InnoDB存储引擎还会对辅助索引的下一个键值加上gap lock,即还有一个辅助索引范围为(3,6)的锁。因此在会话B中运行下面语句会被阻塞

>SELECT * FROM z WHERE a=5 LOCK IN SHARE MODE;

>INSERT INTO z SELECT 4,2;

>INSERT INTO z SELECT 6,5;

第一个SQL语句不能执行,因为在会话A中执行的SQL语句已经对聚集索引中的列a=5的值做了X锁,因此执行会阻塞,第二个SQL语句,主键插入4,没有问题,但是辅助索引2在锁定的范围(1,3)中,因此执行同样会被阻塞。第三个SQL语句,插入主键6没有被锁定,5也不再范围(1,3)之间,但是插入的值5在另一个锁定的范围(3,6)中,故同样需要等待。而下面的SQL语句,不会被阻塞。可以理解执行

>INSERT INTO z SELECT 8,6;

>INSERT INTO z SELECT 2,0;

>INSERT INTO z SELECT 6,7;

从上面的例子可以看到,Gap Lock的作用是为了阻止多个事务将记录插入到同一个范围内,而这会导致Phantom Problem问题的产生。例如上面例子中,会话A中用户已经锁定了b=3的记录,若此时没有Gap Lock锁定(3,6)那么用户可以插入索引b列为3的记录,这样会导致会话A中的用户再次执行同样查询时会返回不同的记录,即导致Phantom Problem问题的产生。

用户可以通过以下两种方式来显式的关闭Gap Lock:

将事务的隔离级别设成RC

将参数innodb_locks_unsafe_for_binlog 设置为1

在上述配置中,除了外键约束和唯一性约束检查依然需要Gap Lock,其余情况仅适用于Record Lock进行锁定,但需要牢记,上述设置破坏了事务的隔离性,并且对于replication,可能会导致主从不一致。此外,从性能上看,RC也不会优于默认的事务隔离级别RR

在InnoDB存储引擎中,对于INSERT操作,其会检查插入记录的下一条记录是否被锁定,若已经被锁定,则不允许查询,对于上面例子,会话A已经锁定了表z中b=3的记录,即已经锁定(1,3)范围,这是若在其他会话插入同样的会导致阻塞

>INSERT INTO t SELECT 2,2;

因为在辅助索引b上插入值为2的记录时,会检测到下一个记录3已经被索引,而将插入的值修改为如下的值,则可以立即执行

>INSERT INTO t SELECT 2,0;

需要再次提醒,对于唯一键值的锁定,Next-Key Lock降级为Record Lock进存在于查询所有的唯一索引列。若唯一索引由多个列组成,而查询仅是查找多个唯一索引列中的其中一个,那么查询其实是range类型查询,而不是point类型查询,故InnoDB存储引擎依然使用Next-Key Lock进行锁定

MySQL中行锁的算法的更多相关文章

  1. MySQL:锁机制和隔离事务级别

    在mysql中的锁看起来是很复杂的,因为有一大堆的东西和名词:排它锁,共享锁,表锁,页锁,间隙锁,意向排它锁,意向共享锁,行锁,读锁,写锁,乐观锁,悲观锁,死锁.这些名词有的博客又直接写锁的英文的简写 ...

  2. Mysql Innodb 锁机制

    latch与lock latch 可以认为是应用程序中的锁,可以称为闩锁(轻量级的锁) 因为其要求锁定的时间必须要非常短,若持续时间长,则会导致应用性能非常差,在InnoDB存储引擎中,latch又可 ...

  3. MySQL InnoDB锁机制

    概述: 锁机制在程序中是最常用的机制之一,当一个程序需要多线程并行访问同一资源时,为了避免一致性问题,通常采用锁机制来处理.在数据库的操作中也有相同的问题,当两个线程同时对一条数据进行操作,为了保证数 ...

  4. 关于mysql 间隙锁

    前段时间系统老是出现update死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...

  5. day 59 MySQL之锁、事务、优化、OLAP、OLTP

    MySQL之锁.事务.优化.OLAP.OLTP   本节目录 一 锁的分类及特性 二 表级锁定(MyISAM举例) 三 行级锁定 四 查看死锁.解除锁 五 事务 六 慢日志.执行计划.sql优化 七 ...

  6. MySQL间隙锁问题

    间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间. 最近用户反馈说系统老是出现insert时,等待超时了,最后发现是ins ...

  7. MySql 中锁的定义

    行级锁,一般是指排它锁,即被锁定行不可进行修改,删除,只可以被其他会话select.行级锁之前需要先加表结构共享锁. 表级锁,一般是指表结构共享锁锁,是不可对该表执行DDL操作,但对DML操作都不限制 ...

  8. mysql 乐观锁、悲观锁、共享锁,排它锁

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  9. 一文详解MySQL的锁机制

    一.表级锁.行级锁.页级锁 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则. MySQL数据库由于其自身架构的特点,存在多种数据存储引擎, ...

随机推荐

  1. docker发布spring cloud应用

    原文地址:http://www.cnblogs.com/skyblog/p/5163691.html 本文涉及到的项目: cloud-simple-docker:一个简单的spring boot应用 ...

  2. ST股福音:涨停潮开始! 最全ST摘帽股汇总!

    本周ST股摘帽行情提前预演,ST股上演涨停潮,部分ST股甚至出现连续涨停.云财经在三季报披露之前曾经做过一期ST股摘帽分析,在三季报正式披 露完毕后,以及部分ST公司公布了2015年年报预告,ST股能 ...

  3. C++ 内存泄漏

    1. 内存泄漏: 在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况. 内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前 ...

  4. poj 2828 Buy Tickets (线段树 单节点 查询位置更新)

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 15533   Accepted: 7759 Desc ...

  5. Atitit  hre框架v5 新特性  HREv5

    Atitit  hre框架v5 新特性  HREv5 1. V5新特性 apiurl2="/wrmiServlet";1 2. V1 新特性1 3. V2 新特性 添加php版1 ...

  6. Angularjs学习笔记5_form1

    1.入门 <form ng-controller="validationController" name="form1" novalidate>   ...

  7. StoryBoard不使用AutoLayout情况下 按比例快速兼容适配iPhone6/6 Plus教程【转载】

    StoryBoard不使用AutoLayout情况下 按比例快速兼容适配iPhone6/6 Plus教程[转] 声明:本文章是为了后期快速兼容6和6Plus的按比例放大方法,对于部分读者来说可能觉得该 ...

  8. libubox组件(1)——usock

    一:相关API介绍 1.相关源码文件:usocket.h usocket.c 2.类型标志 1: #define USOCK_TCP 0 2: #define USOCK_UDP 1 3: #defi ...

  9. 带宽的单位为什么是Hz而不是bps?

    如果从电子电路角度出发,带宽(Bandwidth)本意指的是电子电路中存在一个固有通频带,这个概念或许比较抽象,我们有必要作进一步解释.大家都知道,各类复杂的电子电路无一例外都存在电感.电容或相当功能 ...

  10. github桌面工具commit不了解决

    这样发现github上还是空文件,  因为要重新添加过 1.  git add -A  添加所有文件 2. git commit -m "xxx" 3.  git push -u ...