InnoDB存储引擎的锁

锁的类型

锁的类型包括:

1.     共享锁(S lock),允许事务读取一行数据

2.     排他锁(X lock),允许事务删除或更新一行数据

锁的兼容性a

X

S

X

不兼容

不兼容

S

不兼容

兼容

S和X都是行锁。

InnoDB支持多粒度锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在。为了支持在不同粒度上进行加锁操作,InnoDB支持一种额外的锁方式:意向锁。

意向锁包括:

意向共享锁(IS lock),事务想要获取一张表中某几行的共享锁

意向排他锁(IX lock),事务想要获取一张表中某几种的排他锁

在对记录r加X锁之前,已经有事务对表1进行了S表锁,那么表1上已存在S锁,之后事务需要对记录r在表1上加上IX,由于不兼容,所以该事物需要等待表锁操作的完成。

锁的兼容性b

IS

IX

S

X

IS

兼容

兼容

兼容

不兼容

IX

兼容

兼容

不兼容

不兼容

S

兼容

不兼容

兼容

不兼容

X

不兼容

不兼容

不兼容

不兼容

一致性非锁定读

一致性非锁定读是指InnoDB存储引擎通过行多版本控制的方式来读取当前执行时间数据库中行的数据,不需要等待访问的行上X锁的释放(此时访问的是该行的快照数据)。

行多版本技术:一个行记录可能有不止一个快照数据。

不同的事务隔离级别下,读取的快照数据也会不同。

Read committed隔离级别下:总会读取最新的一份快照数据。

Repeatable read隔离级别下:总会读取事务开始时的行快照数据。

举例来看一致性非锁定读是怎样的情况,以及在不同隔离级别下的特性:(table表只有一个字段id)

Session A

mysql>BEGIN;

mysql>SELECT * FROM table1 WHERE id=1;

在上面回话A中,开启了一个事务,并读取了id=1的记录(假设记录存在表中),但是事务并没有结束。与此同时,再启动另一个回话B

Session B

mysql>BEGIN;

mysql>UPDATE table1 SET id=3 WHERE id=1;

在回话B中更新id=1的值改为3,此时B事务依然没有提交,这样id=1上加了一个X锁。如果此时在A会话中再次读取id=1的记录,根据InnoDB存储引擎的特性,在read committed和repeatable read下会使用一致性非锁定读,此时读取的应该是id=1的记录。

截止在会话B中提交事务。

在B事务提交后,在会话A中再次执行查询,这时候在在read committed和repeatable read下会使用一致性非锁定读,就会得到不一样的查询结果。Read committed下读取的为空,repeatable read下读取的还是id=1的记录。

一致性锁定读

在默认情况下,即事务的隔离级别是repeatable read模式下,InnoDB存储引擎的SELECT操作使用的是一致性非锁定读。但是在某些情况下,用户需要显示的读取数据操作进行加锁保证数据逻辑的一致性。

InnoDB提供了两种方式实现一致性锁定读:

1.     Select … for udpate,对读取的行加了X锁

2.     Select … lock in share mode,对读取的行加了S锁

自增长与锁

自增长字段通常会在表设计时作为主键来用。InnoDB存储引擎对于每张包含自增长字段的表都会有一个自增长计数器维护在内容中。当进行插入操作时,这个计数器会被初始化,插入操作会依据这个自增长的计数器加1赋予自增长列,这个实现方式成为 auto_inc locking。这是一种特殊的表锁机制,为了提高插入性能,所不是在一个事务完成后才释放,而是完成插入操作时就立即释放。

比较新的mysql版本提供了一种轻量级互斥量的自增长机制。

提供属性innodb_autoinc_lock_mode俩控制自增长模式(取值有0、1、2,默认值是1)。

锁的算法

InnoDB存储引擎包含3中行锁的算法:

1.     record lock,单个行记录上的锁

2.     gap lock,锁定一个范围,但不包含本身

3.     next-key lock,等同于gap lock+record lock

若事务T1已经通过next-key locking锁定了如下范围

(10,11]、(11,13]

当插入新的纪录12时,则锁定的范围变为

(10,11] 、(11,12] 、(12,13]

当查询的索引具有唯一特性时,InnoDB存储引擎会对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

该表b是辅助索引,若执行如下sql

Select * from z where b=3 for update

很明显sql会根据辅助索引来查询,使用next-key locking来加锁。并且因为有两个索引,需要分别锁定,对于聚集索引会对a=5的行添加record lock,而对于非聚集索引,会加上next-key lock,会对b列的区间(1,3)锁定,特别注意InnoDB存储引擎还会对辅助索引下一个键值添加上gap lock,即对区间(3,6)锁定。所以对以下sql的执行都会阻塞:

Select * from z where a=5 lock in share mode;

Insert into z select 4,2

Insert into z select 6,5

由此可见gap lock是为了防止多个事务把数据插入到同一范围内,而这会导致Phantom problem。

InnoDB存储引擎的锁的更多相关文章

  1. 图文实例解析,InnoDB 存储引擎中行锁的三种算法

    前文提到,对于 InnoDB 来说,随时都可以加锁(关于加锁的 SQL 语句这里就不说了,忘记的小伙伴可以翻一下上篇文章),但是并非随时都可以解锁.具体来说,InnoDB 采用的是两阶段锁定协议(tw ...

  2. InnoDB 存储引擎的锁机制

    测试环境隔离级别:REPEATABLE-READ 行级别的 - Share and Exclusive Locks 共享锁 S:允许持有S锁的事务对行进行读操作 排他锁 X: 允许持有X锁的事务对行进 ...

  3. 《Mysql技术内幕,Innodb存储引擎》——锁

    lock与latch 在数据库中lock与latch分别指不同的所. latch:可分为互斥量(mutex)和读写锁(rwlock),目的在于保证数据库内部的结构中共享资源并发时能够正确操作,其对象主 ...

  4. MySQL内核:InnoDB存储引擎 卷1

    MySQL内核:InnoDB存储引擎卷1(MySQL领域Oracle ACE专家力作,众多MySQL Oracle ACE力捧,深入MySQL数据库内核源码分析,InnoDB内核开发与优化必备宝典) ...

  5. MySQL数据库InnoDB存储引擎中的锁机制

    MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...

  6. MySQL InnoDB存储引擎中的锁机制

    1.隔离级别 Read Uncommited(RU):这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用. Read Committed (RC):仅能读取到已提交 ...

  7. (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁

    表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...

  8. mysql中InnoDB存储引擎的行锁和表锁

    Mysql的InnoDB存储引擎支持事务,默认是行锁.因为这个特性,所以数据库支持高并发,但是如果InnoDB更新数据的时候不是行锁,而是表锁的话,那么其并发性会大打折扣,而且也可能导致你的程序出错. ...

  9. MySQL技术内幕InnoDB存储引擎(表&索引算法和锁)

    表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示 ...

随机推荐

  1. 用Python实现童年的21款小游戏,有你玩过的吗?(不要错过哦)

    Python为什么能这么火热,Python相对于其他语言来说比较简单,即使是零基础的普通人也能很快的掌握,在其他方面比如,处于灰色界的爬虫,要VIP的视频,小说,歌,没有爬虫解决不了的:数据挖掘及分析 ...

  2. PHP的引用计数是什么意思?

    什么是引用计数 在PHP的数据结构中,引用计数就是指每一个变量,除了保存了它们的类型和值之外,还额外保存了两个内容,一个是当前这个变量是否被引用,另一个是引用的次数.为什么要多保存这样两个内容呢?当然 ...

  3. 启动Jenkins后无法访问,如何排错

    做IT工作,使用各种工具的时候,遇到错误都是一堆英文,对于英语不好的人,看到报错可能就会心烦,我刚开始就是这种状态.后来,遇到问题,首先复制报错信息到百度上搜索,没有人请教的时候,你不能坐等问题自己解 ...

  4. PHP 算法之 -- 计算器设计

    <?php//$exp='300+20*6-20'; $exp='71*2-50*3-3-67*6+80'; //14-15-3=-4 //定义一个数栈和一个符号栈 $numsStack=new ...

  5. 鸿蒙内核源码分析(原子操作篇) | 是谁在为原子操作保驾护航 | 百篇博客分析OpenHarmony源码 | v34.02

    百篇博客系列篇.本篇为: v34.xx 鸿蒙内核源码分析(原子操作篇) | 谁在为原子操作保驾护航 | 51.c.h .o 本篇说清楚原子操作 读本篇之前建议先读鸿蒙内核源码分析(总目录)系列篇. 基 ...

  6. 华为云计算IE面试笔记-华为云计算解决方案业务迁移支持哪些迁移?有哪些特点?请描述基本的业务交付流程、业务迁移流程和原则。

    1. 迁移场景:华为云计算解决方案按照源端环境来说,支持P2V.V2V(P2V:物理设备(操作系统及其上的应用软件和数据)迁移到华为虚拟化平台.V2V:其他厂商的虚拟化平台迁移到华为虚拟化平台.)以及 ...

  7. 更准确的测试Java程序性能——JMH基准测试

    什么是JMH ​ JMH,即Java Microbenchmark Harness,Java平台下的一套微基准测试工具.如果我们需要测试API性能的话,就可以用上这个工具,所以它并不是取代单元测试的. ...

  8. jQuery实现购物车功能

    1.HTML代码(品优购模版) <!DOCTYPE html> <html lang="zh-CN"> <head> <meta char ...

  9. Node.js躬行记(12)——BFF

    BFF字面意思是服务于前端的后端,我的理解就是数据聚合层.我们组在维护一个后台管理系统,会频繁的与数据库交互. 过去为了增删改查会写大量的对应接口,并且还需要在Model.Service.Router ...

  10. firewalld dbus接口使用指南

    firewalld,一个基于动态区的iptables/nftables守护程序,自2009年左右开始开发,最新版本 - 防火墙0.6.3 - 发布于2018年10月11日.主要的开发人员是托马斯·沃纳 ...