InnoDB的锁类型

InnoDB存储引擎支持行锁,锁类型有两种:

  • 共享锁(S锁)
  • 排他锁(X锁)

S和S不互斥,其他均互斥。

除了这两种锁以外,innodb还支持一种锁,叫做意向锁

那么什么是意向锁?为什么需要意向锁呢?

考虑这种情况:

SessionA:已经持有表t某一行的X锁,需要对行进行更新操作

SessionB:想申请表t的表锁写锁

在没有意向锁之前,SessionA已经持有了行X锁以后,如果SessionB也成功,意味着SessionB可以对这个表中的所有数据进行更新操作,与SessionA的行锁是冲突的。

所以数据库在同意SessionB的申请之前,会做以下的判断:

  1. 检查是否有其他的表级写锁存在
  2. 判断表中每一行是否有行级X锁存在

步骤2的判断本身效率不高。所以产生了意向锁,在申请行级锁之前,先申请意向锁,成功之后才能申请行锁。(简单理解为多保存一个变量,便于申请表锁的时候进行快速判断)。

意向锁分为两种:

  • 意向共享锁(IS锁)
  • 意向排他锁(iX锁)

IS锁和IX锁之间彼此都不互斥,IS和IX只和表级别的读写锁互斥。其中:

  • IX和表X和表S互斥
  • IS和表X互斥
一致性锁定读和一致性非锁定读
一致性非锁定读

当隔离类型设置为读已提交和可重复读时,我们写的普通的select语句,不会申请锁,也不会被阻塞,会从MVCC选择一个视图读取数据。

两种隔离状态的区别在于:

  • 读已提交永远拿到的是最新的视图
  • 可重复读永远使用事务刚建立时拿到的视图
一致性锁定读

当写这两种select语句时,会进行加锁操作。

  • select ... lock in share mode

    • 这个语句表示加入一个S锁,其他事务也可以加S锁
    • 使用场景:不同表之间的相同数据保持一致性时使用(存疑,暂时放着)
  • select ... for update
    • 这个语句表示加入一个X锁,其他事务不能读也不能写
    • 使用场景:先读,根据读结果进行修改的操作时可以使用
行锁的三种算法(判断锁定的范围)

InnoDB存储引擎有三种行锁的锁定算法:

  • record lock:锁定单行
  • gap lock:锁定范围,不包含记录本身
  • next-key lock:gap lock + record lock 既锁定范围又锁定记录本身

当select操作需要加锁时,会按照上面的next-key lock进行加锁。

  • 当查询条件中有索引,并且是唯一索引时,可以只锁定单条记录,由next-key lock降级为 record 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;

在sessionA中,输入下面查询语句

select * from z where b=3 for update;

在sessionB中,输入下面查询语句

select * from z where b=1 for update;
select * from z where b=3 for update;
insert into z (a,b) values(4,2);
select * from z where b=6 for update;

其中,第一条和第四条可以正常返回,第二条第三条语句会阻塞,因为SessionA一直没有commit,所以这两条语句阻塞一段时间后会报锁等待超时异常。

mysql> select * from z where b=1 for update;
+---+------+
| a | b |
+---+------+
| 1 | 1 |
| 3 | 1 |
+---+------+
2 rows in set (0.00 sec) mysql> select * from z where b=6 for update;
+---+------+
| a | b |
+---+------+
| 7 | 6 |
+---+------+
1 row in set (0.00 sec) mysql> select * from z where b=3 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into z (a,b) values(4,2);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

结果分析

查询条件为b=3,所以会使用b列的辅助索引来查询,找到记录3后

  • 使用record lock锁定主键索引a=5的记录
  • 使用next-key lock锁定辅助索引(1,3)3 (3,6)这个范围的记录

在SessionA提交事务之前,这个范围内的记录都加的是X排他锁,所以第二条和第三条记录都需要阻塞等待。

MySQL-InnoDB行锁的更多相关文章

  1. Mysql InnoDB行锁实现方式(转)

    Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...

  2. Mysql InnoDB行锁实现方式

    Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...

  3. Mysql InnoDB行锁不使用索引锁表的时候会锁整张表

    原文:http://www.thinkphp.cn/topic/41577.html 如果使用针对InnoDB的表使用行锁,被锁定字段不是主键,也没有针对它建立索引的话.行锁锁定的也是整张表.锁整张表 ...

  4. Mysql研磨之InnoDB行锁模式

    事务并发带来的一些问题 (1)更新丢失(LostUpdate):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题最后的更新覆盖了由其 ...

  5. MySQL锁---InnoDB行锁需要注意的细节

    前言 换了工作之后,接近半年没有发博客了(一直加班),emmmm.....今天好不容易有时间,记录下工作中遇到的一些问题,接下来应该重拾知识点了.因为新公司工作中MySQL库经常出现查询慢,锁等待,节 ...

  6. MySQL锁:03.InnoDB行锁

    目录 InnoDB 行锁 锁排查可以用的视图和数据字典 InnoDB 行锁兼容性 InnoDB行锁之共享锁 共享锁: 查看InnoDB锁 InnoDB行锁实现机制 对普通索引上锁 InnoDB隐式.显 ...

  7. mysql 开发进阶篇系列 9 锁问题 (Innodb 行锁实现方式)

    一.概述 Innodb 行锁是通过给索引上的索引项加锁来实现的.这一点与(oracle,sql server)不同后者是通过在数据块中对相应的数据行加锁.这意味着只有通过索引条件检索数据,innodb ...

  8. Innodb行锁源码学习(一)

    Innodb是mysql数据库中目前最流行的存储引擎,innodb相对其它存储引擎一个很大的特点是支持事务,并且支持行粒度的锁.今天我重点跟大家分享下innodb行锁实现的基础知识.由于篇幅比较大,文 ...

  9. 巧用MySQL InnoDB引擎锁机制解决死锁问题(转)

    该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深 ...

  10. MySQL InnoDB引擎锁的总结

    为什么要锁 我们开的的各式各样系统中,系统运行需要CPU.内存.I/O.磁盘等等资源.但除了硬资源外,还有最为重要的软资源:数据. 当人们访问操作我们的系统时,其实归根是对数据的查看与生产.那么对于同 ...

随机推荐

  1. Windows应用开发-常用工具集推荐

     .NET/WPF开发 Visual Studio 最新版本是VS2022,官网下载:Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 VsColorOutput 控制台 ...

  2. OpenMMLab AI实战营 第七课笔记

    OpenMMLab AI实战营 第七课笔记 目录 OpenMMLab AI实战营 第七课笔记 import os import numpy as np from PIL import Image im ...

  3. 深入剖析数据删除操作:DELETE 语句的使用与管理实践

    title: 深入剖析数据删除操作:DELETE 语句的使用与管理实践 date: 2025/1/8 updated: 2025/1/8 author: cmdragon excerpt: 数据删除( ...

  4. react之Lazy和Suspense(懒加载)

    React.lazy React.lazy 函数能让你像渲染常规组件一样处理动态引入(的组件). 什么意思呢? 其实就是懒加载. 其原理就是利用es6 import()函数.这个import不是imp ...

  5. React基础笔记2

    一.生命周期函数 挂载卸载过程 constructor        props context componentWillMount  服务器与客户端 componentDidMount  ajax ...

  6. 【译】在分析器中使用 Meter Histogram(直方图)解锁见解

    您是否正在与应用程序中的性能瓶颈作斗争?不要再观望了!Visual Studio 2022 在其性能分析套件中引入了 Meter Histogram(直方图)功能,为您提供了前所未有的分析和可视化直方 ...

  7. CDS标准视图:催款级别分配 I_DunningLevelDistribution

    视图名称:催款级别分配 I_DunningLevelDistribution 视图类型:参数视图 视图代码: 点击查看代码 @AbapCatalog.sqlViewName: 'IFIDUNLVLDI ...

  8. uwp IProgress<T>进度通知。

    主要是利用 Pp_ProgressChanged 报告进度: private void BtnDownload_Click(object sender, RoutedEventArgs e) { va ...

  9. WebSocket,IsWebSocketRequest与AspNetWebSocketContext

    asp.net新建一个服务端程序,用来处理链接服务端: 1,新建一个处理程序 .ashx using System; using System.Collections.Generic; using S ...

  10. 认识soui4js(第2篇):代码编辑及调试

    开始 假定您使用向导在d:\jsdemo目录创建一个工程,您也已经安装好了vscode, 那么您应该可以看到下面的界面效果: 工程生成后,主要包含一个soui资源包及一个main.js 要运行这个程序 ...