首页 > 其他分享 >InnoDB锁

InnoDB锁

时间:2024-05-27 19:00:14浏览次数:22  
标签:事务 加锁 记录 索引 InnoDB 意向锁 主键

为什么要加锁?

锁的存在是为了在多个并发请求存取数据的情况下,维护数据一致性

锁分类

共享/排他锁

对行记录加锁 ——行锁

  • 共享锁:S锁,在事务要读取一条记录时,需要先获取该记录的S锁。
  • 排他锁:X锁,在事务要改动一条记录时,需要先获取该记录的X锁。
    X锁与任何锁都不兼容
    对表加锁 ——锁表
    同样有S锁和X锁
    如果一个事务给表加了S锁,别的事务既可以获取该表的S锁,也可以获得表中记录的S锁;但不能获得X锁;
    如果一个事务给表加了X锁,别的事务将不能获取该表的任何锁;

意向锁

意向锁是一种不与行级锁冲突表级锁。事务可能要加共享或者排它锁时,先提前声明一个意向锁

  • 为什么需要意向锁呢?

InnoDB支持表锁和行锁共存,如果事务A获取到某一行的排他锁并未提交,而事务B想要获取同一个表的共享锁。因为S锁和X锁互斥,所以要确保没有其他事务持有表中任意一行的X锁。要如何保证?遍历的话显然效率很差,所以设计了意向锁。

  • 意向锁如何解决这个问题?

在事务获取到某一行的排他锁或共享同时,给该表添加意向排他锁IX或意向共享锁IS,其他事务再想获取该表的排他锁或意向锁,就会检测到表已存在的意向锁,而不需逐行检测。意向锁之间可兼容。

3 记录锁 (Record Lock)

记录锁即行锁。记录锁永远是加在索引上的。

4 间隙锁 (Gap Lock)

为了解决幻读问题,InnoDB引入了间隙锁, 它锁住的是一个区间

5 临键锁(Next-Key Lock)

Next-key锁是记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁。说得更具体一点就是:临键锁会封锁索引记录本身,以及索引记录之前的区间,即它的锁区间是前开后闭,比如(5,10]

插入意向锁

插入意向锁,是插入一行记录操作之前设置的一种间隙锁。这个锁释放了一种插入方式的信号。它解决的问题是:多个事务,在同一个索引,同一个范围区间插入记录时,如果插入的位置不冲突,就不会阻塞彼此

7 自增锁

自增锁是一种特殊的表级别锁,如果表中新增数据时就会去持有自增锁

如果一个事务正在往表中插入记录,所有其他事务的插入必须等待,以便第一个事务插入的行,是连续的主键值

一条SQL是如何加锁的?

RC隔离级别

  • 查询条件是主键 ,会加一个排他锁(X锁),或者说加一个X型的记录锁
  • 查询条件是唯一索引, 需要加两个X锁:唯一索引和主键上

    为什么主键索引上的记录也要加锁呢? 如果并发的一个SQL,是通过主键索引来更新,如果delete语句没有将主键索引上的记录加锁,那么并发的update就会感知不到delete语句的存在,违背了同一记录上的更新/删除需要串行执行的约束。

  • 查询条件是普通索引 , 那么对应的所有满足SQL查询条件的记录,都会加上锁。同时,这些记录对应主键索引,也会上锁
  • 查询条件列无索引, MySQL会走聚簇索引进行全表扫描过滤。每条记录都会加上X锁。但是,为了效率考虑,MySQL在这方面进行了改进,在扫描过程中,若记录不满足过滤条件,会进行解锁操作。同时优化违背了2PL原则。

RR隔离级别

  • 查询条件是主键, 同RC, 加一个排他锁(X锁),
  • 查询条件是唯一索引, 同RC,加了两个X锁,id唯一索引满足条件的记录上一个,对应的主键索引上的记录一个。
  • 查询条件是普通索引,X锁,还会加间隙Gap锁。
  • 查询条件列无索引, 主键索引的所有记录,都将加上X锁,每条记录间也都加上间隙Gap锁。

    在这种情况下,MySQL做了一些优化,即semi-consistent read,对于不满足条件的记录,MySQL提前释放锁,同时Gap锁也会释放

RR隔离级别下,加锁规则

加锁规则一共包括:两个原则、两个优化和一个bug

  • 原则1:加锁的基本单位都是next-key locknext-key lock(临键锁)是前开后闭区间。
  • 原则2:查找过程中访问到的对象才会加锁。
  • 优化1:索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为行锁(Record lock)。
  • 优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock退化为间隙锁(Gap lock)。
  • 一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。

标签:事务,加锁,记录,索引,InnoDB,意向锁,主键
From: https://www.cnblogs.com/wise-mushroom/p/18216281

相关文章

  • mysql innodb purge threads
    在MySQL中InnoDB属于存储引擎层,并以插件的形式集成在数据库中。从MySQL5.5.8开始,InnoDB成为其默认的存储引擎。InnoDB存储引擎支持事务、其设计目标主要是面向OLTP的应用,主要特点有:支持事务、行锁设计支持高并发、外键支持、自动崩溃恢复、聚簇索引的方式组织表结构等。想系统学习......
  • MySQL InnoDB存储引擎
    一、存储引擎的简介MySQL5.7支持的存储引擎有InnoDB、MyISAM、Memory、Merge、Archive、Federated、CSV、BLACKHOLE等。1、InnoDB存储引擎从MySQL5.5版本之后,默认内置存储引擎是InnoDB,主要特点有:(1)灾难恢复性比较好;(2)支持事务。默认的事务隔离级别为可重复读,通过MVCC(并发版本控......
  • mysql中InnoDB的表空间--独立表空间
    大家好,上篇文章我们在讲mysql数据目录的时候提到了表空间这个名词,它是一个抽象的概念,对于系统表空间来说,对应着文件系统中一个或多个实际文件;对于每个独立表空间来说,对应着文件系统中一个名为表名.ibd的实际文件。我们可以把表空间比作存储页的容器,当我们想为某个表插入一条......
  • MySQL的自增ID连续性控制变量innodb_autoinc_lock_mode
    查看innodb_autoinc_lock_mode的值在MySQL命令行客户端中使用“SHOWVARIABLES”查看:MySQL[mydb]>SHOWVARIABLESLIKE'innodb_autoinc_lock_mode';+--------------------------+-------+|Variable_name|Value|+--------------------------+-------+|......
  • MySQL 5.7 InnoDB官方文档中锁的八个分类概述自译
    官方文档描述InnoDB使用的锁的八个分类共享锁(SharedLocks)和排它锁(ExclusiveLocks)InnoDB实现了两种标准的行级别锁,分别是共享锁(又称S锁)和排它锁(又称X锁)。一个共享锁允许持有它的事务去读取某行数据。一个排它锁允许持有它的事务去更新或删除某行数据。如果事务T1持有......
  • mysql5.7 报错:[ERROR] InnoDB: Ignoring the redo log due to missing MLOG_CHECKPOIN
    mysql5.7启动报错:2024-05-19T02:02:14.453082Z0[Warning]TIMESTAMPwithimplicitDEFAULTvalueisdeprecated.Pleaseuse--explicit_defaults_for_timestampserveroption(seedocumentationformoredetails).2024-05-19T02:02:14.453139Z0[Note]--secure-file......
  • 如何选择配置 MySQL innodb_log_file_size
    配置InnoDB的redo空间大小是写密集型工作负载最重要的配置选项之一。不过,这需要权衡利弊。配置的redo空间越大,InnoDB就能更好地优化写IO。不过,增加redo空间也意味着在系统断电或因其他原因崩溃时需要更长的恢复时间。 对于特定的innodb_log_file_size值,要预测系统......
  • MySQL—MySQL的存储引擎之InnoDB
    MySQL—MySQL的存储引擎之InnoDB存储引擎及种类存储引擎说明MyISAM高速引擎,拥有较高的插入,查询速度,但不支持事务InnoDB5.5版本后MySQL的默认数据库存储引擎,支持事务和行级锁,比MyISAM处理速度稍慢ISAMMyISAM的前身,MySQL5.0以后不再默认安装MRG_MyISAM将多......
  • InnoDB常用锁总结(行锁、间隙锁、临键锁、表锁)
    相关文章数据库系列:MySQL慢查询分析和性能优化数据库系列:MySQL索引优化总结(综合版)数据库系列:高并发下的数据字段变更数据库系列:覆盖索引和规避回表数据库系列:数据库高可用及无损扩容数据库系列:使用高区分度索引列提升性能数据库系列:前缀索引和索引长度的取舍数据库系列:My......
  • 17. InnoDB-spaceID.PageNumber/压缩表
    表空间内部组织结构表空间内部由多个段对象(Segment)组成每个段(Segment)由区(Extent)组成每个区(Extent)由页(Page)组成每个页(Page)里面保存数据(或者叫记录Row)段对用户来说是透明的段也是一个逻辑概念目前为止在information_schema中无法找到段的概念重点需要理解......