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. PHP中DirectIO直操作文件扩展的使用

    关于 PHP 的文件操作,我们也将是通过一系列的文章来进行学习.今天我们先学习的是一个很少人使用过,甚至很多人根本不知道的扩展,它与我们日常的文件操作有些许的不同.不过这些差别并不是我们肉眼所能直观看 ...

  2. linux 服务器资源 监控工具

    工具一:vmstat(服务端) 一.vmstat选项参数解释 -V:显示vmstat版本信息 -n:只在开始时显示一次各字段名称 -a:显示活跃和非活跃内存 -d:显示各个磁盘相关统计信息 -D:显示 ...

  3. jQuery has been removed

    jQuery has been removed, 新的项目不要用jQuery了 这些问题都已经有了解决方案 * $()选择器, * $.ajax, * $dom.on("click" ...

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

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

  5. Charles抓包工具断点修改返回内容

    在测试过程中,往往需要让服务器返回指定的内容,测试一些特殊情况.例如列表内容为空.数据异常的情况等.如果通过操作服务器配合构造相应的数据会比较麻烦,甚至不好构造数据.此时,可以使用Charles的断点 ...

  6. django 常用教程网址

    第一:url中反向解析教程网址 https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/#url

  7. P4755-Beautiful Pair【笛卡尔树,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P4755 题目大意 \(n\)个数字的一个序列,求有多少个点对\(i,j\)满足\(a_i\times a_j\le ...

  8. node-gyp项目命名BUG

    当我们编写node原生模块的时候,免不了对node-gyp项目进行命名,在node-gyp进行build的时候,会跟binding.gyp配置文件中的target_name生成对应的原生模块.但是,如 ...

  9. 树莓派3B上手一二

    树莓派3B上手一二 早些时间心血来潮买过一个树莓派,但是当时只是玩一玩,买来按照网上的教程摆弄了一下就闲置了.最近毕业设计,做时序数据分析的相关的工作,刚好想起能够用到树莓派+Node-RED来生成模 ...

  10. 订单峰值激增 230%,Serverless 如何为世纪联华降本超 40%?|双11 云原生实践

    作者 | 朱鹏 导读:2020 年 双11,世纪联华基于阿里云函数计算 (FC) 弹性扩容,应用于大促会场 SSR.线上商品秒杀.优惠券定点发放.行业导购.数据中台计算等多个场景,业务峰值 QPS 较 ...