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. Docker安装flink及避坑指南

    Docker安装flink 导航 无处不在的大数据 安装flink 拉取flink镜像 编写docker-compose.yml 生成启动 查看安装效果 常见坑及解决方案 问题1 问题2 参考   本 ...

  2. 【OWASP TOP10】2021年常见web安全漏洞TOP10排行

    [2021]常见web安全漏洞TOP10排行 应用程序安全风险 攻击者可以通过应用程序中许多的不同的路径方式去危害企业业务.每种路径方法都代表了一种风险,这些风险都值得关注. 什么是 OWASP TO ...

  3. PHP中的输出缓冲控制

    在 PHP 中,我们直接进行 echo . 或者 print_r 的时候,输出的内容就会直接打印出来.但是,在某些情况下,我们并不想直接打印,这个时候就可以使用输出缓冲控制来进行输出打印的控制.当然, ...

  4. pypandoc库实现文档转换

    写在前面: 对于python程序员来说,文件格式之间转换很常用,尤其是把我们爬虫爬到的内容转换成想要的文档格式时.这几天看到一个网站上有许多文章,个人很喜欢,直接复制太麻烦,为了将爬到的html文件以 ...

  5. oracle 基础SQL语句 版本5.7.29

    一.表与用户介绍 oracle安装完成后默认会有很多用户,大致分为2类用户:一类是必需的帐户,一类是存储各种应用的帐户,默认密码如下: oracle自带的也会有很多默认表存在: 二.创建用户.创建表空 ...

  6. Linux虚拟机配置静态ip地址

    使用VMware搭建的虚拟机ip地址经常变动,在这里记录一下虚拟机设置静态ip地址: 首先通过VMware菜单栏编辑->虚拟网络编辑器->NAT设置查看子网ip地址和网关ip: 例如我这里 ...

  7. 洛谷3233 HNOI2014(虚树+dp)

    膜拜一发\(mts\_246,forever\_shi\) 这两位爷是真的无敌! 首先来看这个题,一看题目的数据范围和"关键点"字眼,我们就能得知这是一道虚树题 那就先一如既往的建 ...

  8. ORM框架查询数据库时返回指定的字段

    django model.objects.filter() 查询指定字段 1.model.objects.filter().values('field_name'),单个字段 2.model.obje ...

  9. C++ 与 Visual Studio 2022 和 WSL(五)——WSL2

    Build and Debug C++ with WSL 2 Distributions and Visual Studio 2022 References Build and Debug C++ w ...

  10. python 类方法 静态方法

    属性: 公有属性  (属于类,每个类一份) 普通属性  (属于对象,每个对象一份) 私有属性    (属于对象,跟普通属性相似,只是不能通过对象直接访问) 方法:(按作用) 构造方法 析构函数 方法: ...