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. 利用 uber-go/dig 库管理依赖

    利用 uber-go/dig 库管理依赖 github 地址 官方文档 介绍 dig 库是一个为 go 提供依赖注入 (dependency injection) 的工具包,基于 reflection ...

  2. 迷你商城后端管理系统 ———— stage2 项目的核心代码实现

    应用程序主函数接口 @SpringBootApplication(scanBasePackages = {"org.linlinjava.litemall.db", "o ...

  3. PHP中使用if的时候为什么建议将常量放在前面?

    在某些框架或者高手写的代码中,我们会发现有不少人喜欢在进行条件判断的时候将常量写在前面,比如: if(1 == $a){ echo 111; } 这样做有什么好处呢?我们假设一个不小心的粗心大意,少写 ...

  4. Go学习【02】:理解Gin,搭一个web demo

    Go Gin 框架 说Gin是一个框架,不如说Gin是一个类库或者工具库,其包含了可以组成框架的组件.这样会更好理解一点. 举个 下面的示例代码在这:github 利用Gin组成最基本的框架.说到框架 ...

  5. Linux系列(7) - 链接命令

    硬链接 拥有相同的i节点和存储block块,可以看做事同一个文件 可通过i节点识别 不能跨分区 不能针对目录使用,只能针对文件 软链接 类似Windows快捷方式 软链接拥有自己的i节点和block块 ...

  6. 显式等待until传入自定义方法

    WebDriverWait(driver,10).until(expected_conditions.element_to_be_clickable(ele)) 通过追踪代码,可以发现上面的eleme ...

  7. english note(6.17to6.23)

    6.17 http://www.51voa.com/VOA_Special_English/are-these-us-treasures-about-to-be-destroyed-82260_1.h ...

  8. P6085-[JSOI2013]吃货JYY【状压dp,欧拉回路】

    正题 题目链接:https://www.luogu.com.cn/problem/P6085 题目大意 \(n\)个点的一张无向图,有\(k\)条必走边,\(m\)条其他边,求从\(1\)出发经过必走 ...

  9. 从零开始部署 Yapi(Windows+Nginx)

    一.环境准备及安装 本文中是以本地 Windows 作为安装环境,Nginx 做反向代理,亲测验证可用. Yapi 运行需要的环境: Nodejs,MongoDB 安装包都在文档末尾处 1.1 安装 ...

  10. 关于国密HTTPS 的那些事(二)

    关于国密HTTPS 的那些事(二) 三. 需要解决的问题 前文我们了解了https,并梳理了国密https的流程.那么完成这些流程的目的是什么呢?又是怎么来保护数据的安全性呢?我们继续... 上文我们 ...