MySQL中行锁的算法
行锁的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中行锁的算法的更多相关文章
- MySQL:锁机制和隔离事务级别
在mysql中的锁看起来是很复杂的,因为有一大堆的东西和名词:排它锁,共享锁,表锁,页锁,间隙锁,意向排它锁,意向共享锁,行锁,读锁,写锁,乐观锁,悲观锁,死锁.这些名词有的博客又直接写锁的英文的简写 ...
- Mysql Innodb 锁机制
latch与lock latch 可以认为是应用程序中的锁,可以称为闩锁(轻量级的锁) 因为其要求锁定的时间必须要非常短,若持续时间长,则会导致应用性能非常差,在InnoDB存储引擎中,latch又可 ...
- MySQL InnoDB锁机制
概述: 锁机制在程序中是最常用的机制之一,当一个程序需要多线程并行访问同一资源时,为了避免一致性问题,通常采用锁机制来处理.在数据库的操作中也有相同的问题,当两个线程同时对一条数据进行操作,为了保证数 ...
- 关于mysql 间隙锁
前段时间系统老是出现update死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...
- day 59 MySQL之锁、事务、优化、OLAP、OLTP
MySQL之锁.事务.优化.OLAP.OLTP 本节目录 一 锁的分类及特性 二 表级锁定(MyISAM举例) 三 行级锁定 四 查看死锁.解除锁 五 事务 六 慢日志.执行计划.sql优化 七 ...
- MySQL间隙锁问题
间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间. 最近用户反馈说系统老是出现insert时,等待超时了,最后发现是ins ...
- MySql 中锁的定义
行级锁,一般是指排它锁,即被锁定行不可进行修改,删除,只可以被其他会话select.行级锁之前需要先加表结构共享锁. 表级锁,一般是指表结构共享锁锁,是不可对该表执行DDL操作,但对DML操作都不限制 ...
- mysql 乐观锁、悲观锁、共享锁,排它锁
mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...
- 一文详解MySQL的锁机制
一.表级锁.行级锁.页级锁 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则. MySQL数据库由于其自身架构的特点,存在多种数据存储引擎, ...
随机推荐
- Hibernate中所有包作用详细讲解
http://liyanblog.cn/articles/2012/09/17/1347848802900.html Hibernate一共包括了23个jar包,令人眼花缭乱.本文将详细讲解Hiber ...
- C# t4模版引擎笔记 引入外部dll
<#@ assembly name="D:\Documents\Downloads\Util\Util\bin\Debug\Util.dll" #> <#@ im ...
- AngularJs学习笔记(1)——ng-app
众所周知: ng-app 指令用于告诉 AngularJS 应用当前这个元素是根元素.所有 AngularJS 应用都必须要要一个根元素. 只有被具有ng-app属性的DOM元素包含的元素才会受ang ...
- C语言学习笔记(二) 基础知识
数据类型 C语言数据可以分为两大类: 基本类型数据和复合类型数据: 基本类型数据 整数 整型 (int) ——占4字节 短整型(short int) ——占2字节 长整型(long in ...
- cpu分析简介
进程占用CPU过高,一般有以下两种原因: 1. 业务量过大导致进程处理负荷高,占用CPU资源:2. 程序BUG导致,比如死循环: 初步查看cpu占用情况top进一步 ...
- gulp安装使用
1. 安装nodeJs 2. 全局安装gulp: npm install gulp -g 3. 在cmd切换至项目文件夹下 npm init,创建package.json文件(JSON文件内不 ...
- Blackey win10 + python3.6 + VSCode + tensorflow-gpu + keras + cuda8 + cuDN6N环境配置(转载)
win10 + python3.6 + VSCode + tensorflow-gpu + keras + cuda8 + cuDN6N环境配置 写在前面的话: 再弄这个之前,我对python也好 ...
- webpack issues
webpack-dev-server安装失败 npm ERR! path C:\Users\YYT\Desktop\dot_webpack\node_modules\express\node_modu ...
- X264参考手册
艺搜简介 基本语法: x264 [options]-o outfile infile 注意与ffmpeg的输入输出文件位置恰好相反: ffmpeg[options][[infile options]- ...
- java 读取world的图片 并把图片路径存入数据库
package World; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcep ...