行锁的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. CentOS 6.5 X64 U盘启动盘制作

    本教程是在Linux系统下制件,可以使用虚拟机安装Linux 1.准备一个8G的U盘,在Linux下分成Fat32---500M----root, 剩下的分成Ext3 ----data,并格式化. 2 ...

  2. 【JavaScript】JavaScript DOM 编程

    在开发的时候,最主要是对DOM进行操作.DOM:Document Object Model 文本对象模型. DOM能够以一种独立于平台和语言的方式訪问和改动一个文档的内容和结构. DOM是针对xml( ...

  3. JavaScript之语句

    ECMA-262 规定了一组语句(也称为流控制语句).从本质上看,语句定义了 ECMAScript 中的主要语法,语句通常使用一或多个关键字来完成给定任务. if语句 if语句是最常见的一种语句,语法 ...

  4. IOS设计模式的六大设计原则之依赖倒置原则(DIP,Dependence Inversion Principle)

    定义 高层模块不应该依赖于低层模块,二者都应该依赖于抽象:抽象不应该依赖细节:细节应该依赖抽象. 定义解读 依赖倒置原则在程序编码中经常运用,其核心思想就是面向接口编程,高层模块不应该依赖低层模块(原 ...

  5. 开源播放器ijkplayer源码结构

    ijkplayer核心源码主要在ijkmedia文件夹下ijkplayer.ijksdl及ijkutils. 注:tag k0.3.1 player: remove ijkutil android相关 ...

  6. @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)什么意思??

    从hibernate2.1开始ehcache已经作为hibernate的默认缓存方案(二级缓存方案 sessionfactory级别), 在项目中有针对性的使用缓存将对性能的提升右很大的帮助. 要使用 ...

  7. mysql 1005 错误

    建立外键的时候两个 表的相对应的 类型不一致!

  8. python django -5 进阶

    高级知识点包括: 静态文件处理 中间件 上传图片 Admin站点 分页 使用jquery完成ajax 管理静态文件 项目中的CSS.图片.js都是静态文件 配置静态文件 在settings 文件中定义 ...

  9. 安装Oracle后修改IP总结(转载)

    转载自:http://blog.csdn.net/bleibo/article/details/5447198 安装Oracle后修改IP总结(转载) 针对ORACLE 10G 在安装完后,修改IP ...

  10. springmvc 生命周期

    1A)客户端发出http请求,只要请求形式符合web.xml 文件中配置的*.action的话,就由DispatcherServlet 来处理. 1B)DispatcherServlet再将http请 ...