MySQL之InnoDB中的锁用法

 更新时间:2025年06月26日 08:42:18   作者:在成都搬砖的鸭鸭  
这篇文章主要介绍了MySQL之InnoDB中的锁用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1、背景

为了满足数据库对数据的一致性、事务隔离性、高并发性能需求,就有了锁机制,InnoDB的锁机制是实现事务隔离性和并发控制的核心组件,接下来就来讲一下锁机制相关知识。

2、事务并发问题的三种场景

【1】读读场景

并发读不会有啥问题,这种场景不会对数据有啥影响。

【2】写写场景

并发写会产生脏写,也就是一个事务会修改另一个未提交事务修改过的结果,所以需要锁来进行并发控制,锁的结构如下:

在这里插入图片描述

其字段含义为:

字段含义
事务信息代表这个锁结构属于哪个事务
is_waitingfalse-成功获取到锁,可以修改数据;true-需要等待锁释放

【3】读写或写读场景

这种场景会带来脏读、幻读、不可重复读问题,不同隔离级别可能带来的问题如下:

隔离级别可能带来的问题
READ UNCOMMITTED脏读、不可重复读、幻读
READ COMMIT不可重复读、幻读
REPEATABLE READ幻读
SERIALIZABLE无问题

为了解决脏读、幻读、不可重复读的问题有两种方案:

  • 方案一:读操作使用MVCC,写操作加锁。
  • 方案二:读、写操作都加锁。

3、一致性读

事务利用MVCC进行的读取操作称为一致性读,所有普通的SELECT语句在读已提交、可重复读的隔离级别下都算是一致性读,一致性读不会对记录做加锁操作,其它事务可以修改记录。

4、锁定读

【1】共享锁和独占锁

在使用加锁方式解决并发问题时,要保证读读操作不受影响,写写、读写、写读操作相互阻塞,所以将锁分为了两类,共享锁和独占锁,其含义为:

名称含义
共享锁简称S锁,事务读取一条记录时,需要先获取该记录的锁
独占锁也叫排他锁,简称X锁,在事务改动一条记录时,需要先获取该记录的X锁

【2】锁定读的两种语句

对读取的记录加s锁:

SELECT … LOCK IN SHARE MODE;

对读取的记录加x锁:

SELECT … FOR UPDATE;

5、写操作

DELETE:

对一条记录做DELETE操作的过程是先获取该记录在B+树中的位置,然后获取这条记录的x锁,再执行delete mark操作。我们可以把在B+树中找这条记录的过程看成一个获取x锁的锁定读。

UPDATE:

1、如果未修改该记录的键值并且被更新的列占用的存储空间在修改前后未发生变化,就先在B+树中定位这条记录的位置,然后再获取一下记录的x锁,最后在原位置进行修改操作。可以把这个在B+树中定位修改记录的过程看出有个获取x锁的锁定读。

2、如果未修改该记录的键值并且至少有一个被更新的列占用的存储空间在修改前后发生了变化,就先在B+树中获取这条记录的位置,然后获取这条记录的x锁,将该记录彻底删掉也就是移入垃圾链表,最后再插入一条新记录,这个在B+树中找到要删除的记录的过程可以看成一个获取x锁的锁定读,新插入的记录由INSERT操作提供的隐式锁进行保护。

3、如果修改了该记录的键值,相当于在原记录上做DELETE操作再来一次INSERT操作,加锁规则就按照DELETE和INSERT的规则进行。

INSERT:

通过隐式锁来保护插入的这条记录不被其它事务访问。

6、InnoDB中的表级锁

【1】表级别的S锁、X锁

在对某个表执行SELECT、INSERT、DELETE、UPDATE语句时,InnoDB存储引擎是不会为这个表添加表级别的s锁或x锁的。

对某个表执行ALTER TABLE、DROP TABLE这类DDL语句时和SELECT、INSERT、DELETE、UPDATE语句是相互阻塞的,这个阻塞是通过server层中的元数据锁(简称MDL)来实现的。

【2】表级别的IS锁、IX锁

IS锁和IX锁的含义如下:

名称含义
IS锁意向共享锁,当事务准备在某条记录上加S锁时,需先在表级别加一个IS锁
IX锁意向独占锁,当事务准备在某条记录上加X锁时,需先在表级别加一个IX锁

【3】表级别的AUTO-INC锁

主键自增id,也就是带AUTO_INCREMENT属性的列就使用AUTO-INC锁。

7、InnoDB中的行级锁

【1】LOCK_REC_NOT_GAP行锁类型

这个类型锁分为s锁和x锁,和我们前面讲的共享锁和独占锁一样。

【2】LOCK_GAP行锁类型

这个类型的锁会阻塞当前加锁的这条记录和上一条记录之间的间隙插入。

【3】LOCK_ORDINARY行锁类型

这个类型的锁会保护当前被锁住的记录,并且阻塞这条记录和上一条记录的间隙插入。

【4】Insert Intention Locks行锁类型

被间隙阻塞插入的记录就会有有这样一个类型的锁结构。

【5】隐式锁

保护事务插入时的并发问题。

8、总结

InnoDB锁机制的背景是在保护事务隔离性的前提下最大化并发性,通过MVCC、行锁、表锁的协同,满足高并发场景需求。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL如何给查出的数据加上序号(最新整理)

    MySQL如何给查出的数据加上序号(最新整理)

    这篇文章主要介绍了MySQL如何给查出的数据加上序号,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-04-04
  • MySQL数据库SSL安全连接方式

    MySQL数据库SSL安全连接方式

    本文主要介绍了MySQL 8.0.43的SSL配置和使用方法,包括SSL证书的创建、SSL连接的配置、SSL用户的安全设置以及SSL登录的实现,SSL可以确保数据在传输过程中的机密性、完整性和身份验证,从而提高数据库的安全性
    2025-11-11
  • PHP学习散记 2012_01_07(MySQL)

    PHP学习散记 2012_01_07(MySQL)

    数据库是Web大多数应用开发的基础。如果你是用PHP,那么大多数据库用的是MYSQL也是LAMP架构的重要部分
    2012-01-01
  • 探索MySQL 8中utf8mb4释放多语言数据的强大潜力

    探索MySQL 8中utf8mb4释放多语言数据的强大潜力

    这篇文章主要为大家介绍了探索MySQL 8中utf8mb4释放多语言数据的强大潜力,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • MySQL数据过滤与计算字段实战指南

    MySQL数据过滤与计算字段实战指南

    本文介绍了MySQL数据过滤与计算字段的实战技术,包括多条件组合、通配符过滤、正则表达式搜索和计算字段的使用,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • mysql多表查询的几种分类详细

    mysql多表查询的几种分类详细

    本文主要介绍了mysql多表查询的几种分类详细,主要包括3大分类,等值连接 vs 非等值连接,自连接 vs 非自连接,内连接 vs 外连接,文章介绍的非常详细,感兴趣的可以了解一下
    2022-02-02
  • mysql-5.7.42升级到mysql-8.2.0(二进制方式)

    mysql-5.7.42升级到mysql-8.2.0(二进制方式)

    随着数据量的增长和业务需求的变更,我们可能需要升级MySQL,本文主要介绍了mysql-5.7.42升级到mysql-8.2.0(二进制方式),具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • MySQL 聚簇索引、非聚簇索引与回表详解

    MySQL 聚簇索引、非聚簇索引与回表详解

    本文我们从数据库物理存储的底层逻辑出发,系统拆解了聚簇索引与非聚簇索引的核心概念、存储结构、查询流程,以及"回表"操作的本质,感兴趣的朋友跟随小编一起看看吧
    2026-02-02
  • MySQL笔记之修改数据的解决方法

    MySQL笔记之修改数据的解决方法

    本篇文章介绍了,在mysql中修改数据的解决方法。需要的朋友参考下
    2013-05-05
  • MySQL Workbench中的权限设置不生效

    MySQL Workbench中的权限设置不生效

    MySQL账号即使只被授予特定数据库权限,仍可能因拥有全局权限而查看所有数据库,本文分析该现象成因,提供排查方法,并给出三种解决方案,感兴趣的可以了解一下
    2026-04-04

最新评论