Mysql引擎innodb行锁的三种算法

2023-05-16

Mysql中的锁

基于锁的属性分类:共享锁、排他锁。

基于锁的状态分类:意向共享锁、意向排它锁

根据锁的粒度分类:全局锁、页锁、表级锁、行锁(记录锁、间隙锁、和临键锁),实际上的锁就这些,上面两种分类只是站在不同维度上看这些锁

行锁的三种算法

Record Lock(记录锁)

(1)记录锁是一种行级锁, 仅仅锁住索引记录的一行,在单条索引记录上加锁。

(2)record lock锁住的永远是索引,或者说主键,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。

查询语句必须为精准匹配 = ,不能为 >、<、like等,否则会退化成临键锁。

所以说当一条sql没有走任何索引时,那么将会在每一条聚合索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。
(2)READ COMMITTED级别下仅采用Record Lock.

  • 使用记录锁

    查询

     -- 事务1,查询id为7182的行,不提交
     begin;
     
     select * from w_word where id =7182 for update
     
     commit;
    

    更新

    -- 事务2,事务1如果不提交,此时执行下面的update语句会阻塞
    begin;
    
    update w_word set creator_user ='check' where id=7182
    
    commit;
    
    

    如图

Gap Lock(间隙锁)

间隙锁,锁定一个范围,单不包含记录本身。

(1)区间锁是一种行级锁, 仅仅锁住一个索引区间(开区间,不包括双端端点)。

(2)在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身。
比如在 1、2、3中,间隙锁的可能值有 (∞, 1),(1, 2),(2, ∞),

(3)间隙锁可用于防止幻读,保证索引间的不会被插入数据

  • 产生的条件
  1. 可重复读的隔离级别
  2. 范围条件而不是相等条件索引数据
  3. 请求共享或排他锁时
  • 间隙锁的危害

    锁定整个范围内所有的索引键值,即使这个键值并不存在,无法插入锁定键值范围内的任何数据

  • 解决的问题

    解决了RR(可重复读)级别下幻读的问题

  • 使用间隙锁解决幻读

    表数据

    锁住间隙(7182,7185)

    中间只有记录7183

    begin;
    
    select * from w_word where id > 7182 and id < 7185 for update
    
    

  • 插入记录7184

    begin;
    
    INSERT INTO cloud_learning.w_word
    (id, word)
    VALUES(7184, 'splurge1231');
    
    commit;
    

    此时锁住的(7182,7185)之间多了一条数据7184,造成幻读,间隙锁的作用也产线了。

    select * from w_word where id > 7182 and id < 7185 for update
    

  • 解决幻读

    直接进行7183的查询for update,将会锁住(7182,7185)间隙,7183必须是不存在的记录,否则只会锁住7183这条记录

    select * from w_word where id=7183 for update;
    

    插入7184,这时候就阻塞住了,不会插入(71827185)间隙

    INSERT INTO cloud_learning.w_word
      (id, word)
      VALUES(7184, 'splurge1231');
    

    对于指定查询某一条记录的加锁语句,如果该记录不存在,会产生记录锁和间隙锁,如果记录存在,则只会产生记录锁,如:WHERE id = 7182 FOR UPDATE;

    对于查找某一范围内的查询语句,会产生间隙锁,如:WHERE id BETWEEN 5 AND 7 FOR UPDATE;

  • 普通索引的间隙锁

    在普通索引列上,不管是何种查询,只要加锁,都会产生间隙锁,这跟唯一索引不一样;
    在普通索引跟唯一索引中,数据间隙的分析,数据行是优先根据普通索引排序,再根据唯一索引排序。

Next-key Lock(临键锁)

Next-key Lock:记录锁+Gap锁(间歇锁),即:既包含索引记录,又包含索引区间,主要是为了解决幻读。

同时锁住记录和间隙,前开后闭区间(a,b]。

  • 表结构

    lock_key建立了普通索引

    该表中 lock_key 列潜在的临键锁有:
    (-∞, 12],
    (12, 31],
    (31, 35],
    (35, +∞],

    在事务 A 中执行如下命令:

    非唯一索引列 锁住lock_key=31这条记录;

    begin;
    
    select * from test_lock where lock_key =31 for update
    

    之后如果在事务 B 中执行以下命令,则该命令会被阻塞:

    begin;
    
    INSERT into test_lock (id, lock_key) VALUES(36, 34);
    

    事务 A 在对 lock_key 为 31 的列进行 for update 操作的同时,也获取了 (31, 35] 这个区间内的临键锁。

  • Next-Key Locking实现应用程序的唯一性检查

    如果需要插入的值是唯一的,那么插入之前需求判断唯一性,此时并发会出现问题,但是如果加上lock in share mode,就不会出现问题,如图:

  • 临间锁的退化

    场景退化
    唯一索引,=值匹配记录锁
    唯一索引,=值匹配,但记录不存在间隙锁
    唯一索引范围匹配(<>)记录锁+间隙锁
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql引擎innodb行锁的三种算法 的相关文章

  • MySQL - 重命名列

    如何重命名 mysql 列help to content在我的桌子上tbl help mysql query ALTER TABLE tbl help CHANGE COLUMN help content 您必须在更改列语句中包含列的定义
  • 在数据库中存储差异的最紧凑方式是什么?

    我想实现类似于维基媒体的修订历史的东西 最好使用的 PHP 函数 库 扩展 算法是什么 我希望差异尽可能紧凑 但我很高兴只能显示每个修订版与其同级修订版之间的差异 并且一次只能回滚一个修订版 在某些情况下 只有几个字符可能会发生变化 而在其
  • sqlalchemy 中的随机 ID(pylon)

    我正在使用 pylons 和 sqlalchemy 我想知道如何将一些随机 id 作为primary key 最好的方法是使用随机生成的 UUID import uuid id uuid uuid4 uuid 数据类型在某些数据库中本机可用
  • 在旧版本的 MySQL (<5.5.0) 中模拟 TO_SECONDS()

    出于性能和简单性的原因 我想以秒的形式获取 MySQL 3 x 服务器中 DATETIME 列的内容 或者实际上任何数字类型 我只是想在使用 UNIX TIMESTAMP 时避免所有明显的时区问题 the我表中的日期确实来自不同的区域设置
  • 找时间通过 PHP 执行 MySQL 查询

    我在互联网上看到过这个问题 here http www phpbuilder com board showthread php t 2100256 and here http answers yahoo com question index
  • 存储过程函数中的动态表名

    我编写了一个存储过程函数来从表中获取名称 问题是我希望将表名作为参数传入 有几个不同的表我需要使用此函数 DELIMITER CREATE DEFINER root localhost FUNCTION getName tableName
  • 如何通过 MySQL Workbench 或 CLI 或 MySQLWeb 数据库管理应用程序连接到 Pivotal Cloud Foundry (PCF) 上的 MySQL 服务?

    我有一个Spring Boot based REST部署在的应用程序Pivotal Cloud Foundry PCF 并且工作正常 但是这个 REST 应用程序到目前为止还没有任何数据库连接 因此 我决定安装MySQL服务于PCF从市场上
  • 如何获取 JDBC 中 UPDATE 查询影响的所有行?

    我有一项任务需要使用更新记录PreparedStatement 一旦记录被更新 我们知道更新查询返回计数 即受影响的行数 但是 我想要的不是计数 而是受更新查询影响的行作为响应 或者至少是受影响的行的 id 值列表 这是我的更新查询 UPD
  • 如何使用外连接和分组依据在查询中包含 NULL 值

    我有两个表 其中包含以下示例数据 Table 1 item name item id item desc 1 apple 2 orange 3 banana 4 grape 5 mango Table 2 user items user i
  • 将sql查询结果写入mysql中的文件

    我正在尝试使用 mysql 将查询结果写入文件 我在一些地方看到了有关 outfile 构造的一些信息 但似乎这只将文件写入正在运行 MySQL 的机器 在本例中是远程机器 即数据库不在我的本地机器上 或者 我还尝试运行查询并从 mysql
  • pyodbc 无法正确处理 unicode 数据

    我确实使用 pyodbc 成功连接了 MySQL 数据库 并且它可以很好地处理 ascii 编码的数据 但是当我打印使用 unicode utf8 编码的数据时 它引发了错误 UnicodeEncodeError ascii codec c
  • Python 子进程、mysqldump 和管道

    我在尝试构建简单的备份 升级数据库脚本时遇到问题 错误出现在使用子进程的 mysqldump 调用中 cmdL mysqldump user db user password db pass domaindb gzip gt databas
  • VIEW for 表结合 UNION ALL 的 MySQL 性能

    假设我有 2 张桌子MySQL create table persons id bigint unsigned not null auto increment first name varchar 64 surname varchar 64
  • 重用 PDO 语句 var 会使进程崩溃

    我重用一个变量来存储两个不同的 PDO mysql 语句 stmt dbh gt prepare SELECT stmt gt execute stmt dbh gt prepare UPDATE crash here Error in o
  • Chart.js - 使用 mysql 和 php 从数据库获取数据

    我正在尝试将静态数据转换为使用数据库结果 我将使用MySQL and PHP 示例代码 var randomScalingFactor function return Math round Math random 100 var lineC
  • MySQL - 从另一个表插入与常量合并的数据

    我有一个包含一些数据的临时表 products temp 并且我有另一个需要将数据插入其中的表 产品 我需要在新记录上手动设置一些常量 例如vendor id 1等 是否可以在一次请求中插入临时表数据和常量 临时产品 product nam
  • 关于 Cassandra 与 MySQL 的一些建议

    几天前我在这里问了一个问题 得到了一些非常好的答案 我正在考虑做一个带有个人资料 个人简介等的facebook风格的网站 并询问我是否应该使用mysql 答案是使用Cassandra 因为好多了 我只是问这是每个人都会建议的 只是我对mys
  • 如何绑定值 INSERT INTO mysql perl

    我有下面的代码可以工作 但我需要知道如何绑定它们以确保安全 如果我只是将 new row 替换为 并将其放入执行中我收到错误 感谢您的帮助 foreach my field account field order new row param
  • 使用多个 WHERE 子句更新 Codeigniter 中的批次

    我查看了 CI 用户指南来了解如何处理update batch 并且它似乎只接受一个索引来匹配要更新的行 但在我的例子中 我需要指定两个索引 例如lang and id page我一起用作索引 这样的lang en id page 115是
  • 当php脚本通过ajax运行时显示进度条

    我有一个通过 ajax 向服务器提交值的表单

随机推荐

  • mapreduce编程实例python-使用Python语言写Hadoop MapReduce程序

    原标题 xff1a 使用Python语言写Hadoop MapReduce程序 Python部落 python freelycode com 组织翻译 xff0c 禁止转载 xff0c 欢迎转发 在本教程中 xff0c 我将描述如何使用Py
  • MySQL主从状态检查

    1 查看A B数据库同步状态 输入以下命令 xff0c 会出来很多信息 xff0c 但是主要看Slave IO Running与Slave SQL Running这两个字段都显示yes就行了 MySQL span class token o
  • linux 下对CPU压测的两种方法

    常用的对CPU进行压测是通过计算圆周率让CPU高负荷运作 xff0c 以达到考验CPU计算能力与稳定性的目的 下面介绍两种对CPU进行压测的方法 xff1a 第一种 xff1a bc计算圆周率 root span class hljs va
  • 共生矩阵

    cooc feature image Regions Image LdGray Direction Energy Correlation Homogeneity Contrast Regions xff1a 要计算的区域 image xff
  • Linux驱动学习--android声卡之蓝牙‘sco over hci‘ 通话的使用配置(基于tinyalsa库)

    目录 一 引言 二 sco over hci gt HCI接口 gt 驱动中的 sco over hci 开关 三 声卡中PCM的使用配置 基于tinyalsa库 tiny工具 gt tiny 工具的使用 gt tinycap tinypl
  • leetcode-105.从前序与中序遍历序列构造二叉树

    题目 给定两个整数数组 preorder 和 inorder xff0c 其中 preorder 是二叉树的先序遍历 xff0c inorder 是同一棵树的中序遍历 xff0c 请构造二叉树并返回其根节点 示例 1 输入 preorder
  • 完整的扣减库存方案

    扣减库存方案设计 扣减库存步骤 查询库存 判断是否超出库存 开始扣减 付款 第三四步可以互换 遇到的问题 超卖现象 用户 A 和 B 成功下单 xff0c 在支付时扣减库存 xff0c 当前库存数为 10 因 A 和 B 查询库存时 xff
  • shell脚本标准输出赋值给变量

    方案一 xff1a bin bash string 61 34 hello world 34 result 61 echo string echo result 方案二 xff1a bin bash string 61 34 hello w
  • leetcode-99.恢复二叉搜索树

    题目 给你二叉搜索树的根节点 root xff0c 该树中的 恰好 两个节点的值被错误地交换 请在不改变其结构的情况下 xff0c 恢复这棵树 示例 1 xff1a 输入 xff1a root 61 1 3 null null 2 输出 x
  • 沟通中经常用到的几个库存术语

    周转库存 周转库存是商业企业为了完成商品流转计划 xff0c 保证市场正常供应 xff0c 根据商品销售任务 商品流通环节和速度应保持一定数量的周转需要的商品库存 商业企业的周转库存 xff0c 是组织商品流通必不可少的物质基础 周转库存量
  • 聊一聊什么是SaaS,以及遇到的问题......

    1 软件即服务 SaaS 的定义 SaaS是Software as a Service的缩写 xff0c 意为软件即服务 SaaS是一种软件部署模式 xff0c 第三方供应商在云基础设施上构建应用程序 xff0c 并以订阅的形式 xff0c
  • 斐波那契数列的递归优化《备忘录递归》

    暴力递归 斐波那契数列的数学形式就是递归 xff0c 直接上代码 xff1a span class token keyword public span span class token keyword static span span cl
  • SaaS多租户数据隔离的三种解决方案

    什么是SaaS xff1f SaaS是Software as a Service的缩写 xff0c 意为软件即服务 SaaS是一种软件部署模式 xff0c 第三方供应商在云基础设施上构建应用程序 xff0c 并以订阅的形式 xff0c 通过
  • 值得收藏的几个postman特色功能帮你事半功倍!

    为什么选择postman xff1f 目前市面上提供了以下几种接口测试工具 xff1a Apifox apifox的官方的定位是 xff1a Apifox 61 Postman 43 Swagger 43 Mock 43 JMeter 有桌
  • 看看大神是怎么在spring中运用设计模式的

    Spring中涉及的设计模式总结 1 简单工厂 非23种设计模式中的一种 实现方式 xff1a BeanFactory Spring中的BeanFactory就是简单工厂模式的体现 xff0c 根据传入一个唯一的标识来获得Bean对象 xf
  • JVM调参,看这一篇就够了

    文章目录 JVM相关参数调试内存相关垃圾回收器相关配置方式命令参考 JVM相关参数调试 通过实战的 方式来进行参数调试 xff0c 观察结果才能真正理解含义 xff0c 下面将通过一段代码 xff0c 来一个一个参数的进行测试 代码示例 后
  • JVM的内存结构

    JVM入门 jvm基础 什么是jvm 定义 xff1a Java Virtual Machine java 程序的运行环境 xff08 java 二进制字节码的运行环境 xff09 好处 xff1a 一次编写 xff0c 到处运行的基石自动
  • leetcode-3.无重复字符的最长子串

    给定一个字符串 s xff0c 请你找出其中不含有重复字符的 最长子串 的长度 示例 1 输入 s 61 abcabcbb 输出 3 解释 因为无重复字符的最长子串是 abc xff0c 所以其长度为 3 示例 2 输入 s 61 bbbb
  • 如何重启 Windows 10 子系统(WSL) ubuntu

    如何重启 Windows 10 子系统 xff08 WSL ubuntu WSL 子系统是基于 LxssManager 服务运行的 只需要将 LxssManager 重启即可 可以做成一个 bat 文件 net stop LxssManag
  • Mysql引擎innodb行锁的三种算法

    Mysql中的锁 基于锁的属性分类 xff1a 共享锁 排他锁 基于锁的状态分类 xff1a 意向共享锁 意向排它锁 根据锁的粒度分类 xff1a 全局锁 页锁 表级锁 行锁 xff08 记录锁 间隙锁 和临键锁 xff09 xff0c 实