MySQL45讲之InnoDB加锁规则

前言

本文介绍 MySQL InnoDB 的加锁规则,以及一些需要注意的点。

总结

可重复读隔离级别下,两个原则,两个优化,一个 bug:

原则1:加锁的基本单位是 next-key 锁,是一个前开后闭区间
原则2:查找过程中访问到的记录才会加锁

优化1:索引的等值查询,唯一索引加锁时,next-key 会退化为行锁
优化2:索引的等值查询,向右遍历时且最后一个值不符合时,最后一个 next-key 会退化为间隙锁

一个bug:唯一索引上的范围查询会访问到第一个不满足条件的值为止。

注意,以上的加锁规基于版本 MySQL 5.x

提交读隔离级别下,一个优化:语句执行过程中加的行锁,在语句执行完成后,会把不符合条件的行锁释放,不需要等待事务提交。

注意

1、lock in share mode 和 for update 的区别

使用 lock in share mode 上锁读时,可以进行索引覆盖,那么只会对覆盖索引树上锁,而不会对主键索引树上锁。使用 for update 上锁读时,系统认为接下来需要进行更新操作,所以会给符合条件的记录加上行锁。

这个指导我们, 如果想用 lock in share mode 加读锁来避免记录被更新,那么需要避免索引覆盖的情况,否则通过主键索引还是可以修改记录。

2、使用 limit 可以减小加锁范围

当对 limit 数量的记录执行完操作后,将不再扫描后续的记录,也就不会再加锁。

3、虽然分析加锁区间用 next-key,但注意 next-key 是行锁和间隙锁的组合

看下图的事务流程:

MySQL45讲之InnoDB加锁规则

你或许会疑问,session B 不是没有申请到 next-key 么。

是这样的,申请 next-key 分为两步,session B 首先申请 (5,10)的间隙锁,申请成功;然后申请 c=10 的行锁,阻塞,即申请 next-key 阻塞是阻塞在申请行锁的时候。因为 session B 申请了(5,10)的间隙锁,所以 session A 插入(8,8,8)阻塞。

参考

Original: https://www.cnblogs.com/flowers-bloom/p/mysql45-lock-rule.html
Author: flowers-bloom
Title: MySQL45讲之InnoDB加锁规则

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/508110/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • JavaScript 获取 Url 上的参数(QueryString)值

    获取URL里面传的参数,在Js中不能像后台一样使用Request.QueryString来获取URL里面参数,下面介绍两种方式用来获取参数 方式一:使用split分隔来获取,这种方…

    数据库 2023年6月9日
    084
  • leetcode 543. Diameter of Binary Tree 二叉树的直径(简单)

    给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。 示例 :给定二叉树 1 / \ 2 3 / \ …

    数据库 2023年6月16日
    098
  • 页面静态化

    网站的首页频繁被访问,为了提升访问速度,除了我们之前已经学过的使用缓存技术外,还可以使用页面静态化技术。 页面静态化即将动态渲染生成的页面结果保存成html文件,放到静态文件服务器…

    数据库 2023年6月14日
    083
  • MySQL学习(1)—MySQL概述

    什么是数据库 概述 数据库(Database)是长期存储在计算机内有组织、大量、共享的数据集合。它可以供各种用户共享,具有最小冗余度和较高的数据独立性。数据库管理系统DBMS(Da…

    数据库 2023年6月14日
    098
  • Are You OK?主键、聚集索引、辅助索引

    每张表都一定存在主键吗? 关于这个问题,各位小伙伴们不妨先自己想一想,再往下寻找答案。 首先公布结论: 对于 InnoDB 存储引擎来说,每张表都一定有个主键(Primary Ke…

    数据库 2023年6月6日
    085
  • HackerRank第一趴–Basic Select

    ID number NAME VARCHAR2(17) COUNTRYCODE VARCHAR2(3) DISTRICT VARCHAR2(20) POPULATION numbe…

    数据库 2023年5月24日
    058
  • 笔记-docker学习-2

    继续之前的docker学习 16、 docker commit从容器创建一个新的镜像 OPTIONS说明: -a :提交的镜像作者; -c :使用Dockerfile指令来创建镜像…

    数据库 2023年6月9日
    079
  • 三道MySQL联合索引面试题,淘汰80%的面试者,你能答对几道

    众所周知MySQL 联合索引遵循最左前缀匹配原则,在少数情况下也会不遵循(有兴趣,可以翻一下上篇文章)。 创建 联合索引的时候,建议优先把区分度高的字段放在第一列。 至于如何计算分…

    数据库 2023年5月24日
    076
  • 记一次配置Linux服务器配置ssh登陆方式

    测试系统信息: 1.在目标机器中添加文件 vi /root/.ssh/authorized_keys //创建文件authorized_keys, 需要使用哪个用户登录,就在对应的…

    数据库 2023年6月11日
    091
  • MYSQL(进阶篇)——一篇文章带你深入掌握MYSQL

    MYSQL(进阶篇)——一篇文章带你深入掌握MYSQL 我们在上篇文章中已经学习了MYSQL的基本语法和概念 在这篇文章中我们将讲解底层结构和一些新的语法帮助你更好的运用MYSQL…

    数据库 2023年5月24日
    098
  • 2 Java中 == 和 equals 和 hashCode 的区别

    ==是一个比较运算符; 若比较的是基本数据类型,则比较的是值; 若比较的是引用数据类型,则比较的是它们在内存中的内存地址。 说明:对象是存放在堆中,栈中存放的是对象的引用,因此==…

    数据库 2023年6月6日
    0104
  • 类加载器ClassLoader

    1.双亲委派模型 java是根据双亲委派模型的加载类的,当一个类加载器加载类时,会先尝试委托给父类加载器去加载,直到到达启动类加载器顶层若加载不了,则再让子类加载器去加载直到类成功…

    数据库 2023年6月16日
    0110
  • Linux 下统计文件夹下文件的数量

    1、查看当前目录下的文件数量(不包含子目录中的文件) 2、查看当前目录下的文件数量(包含子目录中的文件) 3、 查看当前目录下的文件夹目录个数(不包含子目录中的目录),同上述理,如…

    数据库 2023年6月14日
    083
  • 线程的生命周期

    线程的生命周期​ 线程具有生命周期,其中包含 5种状态(出生状态,就绪状态,运行状态、暂停状态、死亡状态)。 出生状态就是线程被创建时的状态:当线程对象调用 start()方法 后…

    数据库 2023年6月16日
    0119
  • MySQL错误日志出现“IP address ‘xxx.xxx.xxx.xxx’ could not be resolved: Name or service not known”浅析总结

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/kerrycode/p/15264962.htmlAut…

    数据库 2023年6月11日
    098
  • git 开发规范

    开发总结最重要的是文档和开发流程 文档最重要:记录开发学习的内容,可以是一种总结,此为其一。留下文档可助后生快速入门,减少学习和指导成本,此为其二。来日需要对项目二次开发或者重构追…

    数据库 2023年6月9日
    0143
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球