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数据库操作接口

    文章主要介绍了如何在Node.js中使用mysql模块连接MySQL数据库,并通过Express框架实现数据库操作接口,前端可以通过Axios库与后端进行交互,实现数据操作
    2024-11-11
  • MySQL的Replace into 与Insert into on duplicate key update真正的不同之处

    MySQL的Replace into 与Insert into on duplicate key update真正的不同

    今天听同事介绍oracle到mysql的数据migration,他用了Insert into ..... on duplicate key update ...,我当时就想怎么不用Replace呢,于是回来就仔细查了下,它们果然还是有区别的
    2014-02-02
  • MySQL索引查询limit offset及排序order by用法

    MySQL索引查询limit offset及排序order by用法

    这篇文章主要介绍了MySQL限制数据返回条数limit offset及排序order by用法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • linux采用binary方式安装mysql

    linux采用binary方式安装mysql

    这篇文章主要为大家详细介绍了linux采用binary方式安装mysql步骤,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • MySQL一对多查询的实现示例

    MySQL一对多查询的实现示例

    一对多连接查询就是其中一种常见的查询方式,它可以将一张表中的一行记录与多张表中的多行记录关联起来,并将其结果输出,本文就来介绍一下如何使用,感兴趣的可以了解一下
    2023-10-10
  • MySQL数据库wait_timeout参数详细介绍

    MySQL数据库wait_timeout参数详细介绍

    这篇文章主要介绍了MySQL数据库wait_timeout参数详细介绍的相关资料,wait_timeout是MySQL中用于控制非交互式连接等待时间的系统变量,影响服务器资源管理和安全性,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-12-12
  • 使用Mysql5.x以上版本出现报错#1929 Incorrect datetime value: '''''''' for column ''''createtime''''的快速解决方法

    使用Mysql5.x以上版本出现报错#1929 Incorrect datetime value: '''''''' f

    我的MySQL安装后,保存删除表数据总是出现#1929 Incorrect datetime value: '' for column 'createtime' 的报错提醒,导致不能删除表里数据。下面小编给大家分析原因及解决办法,需要的朋友可以参考下
    2017-01-01
  • Mybatis特殊字符处理的详解

    Mybatis特殊字符处理的详解

    这篇文章主要介绍了Mybatis特殊字符处理的详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • Mysql数据库分库和分表方式(常用)

    Mysql数据库分库和分表方式(常用)

    本文主要给大家介绍Mysql数据库分库和分表方式(常用),涉及到mysql数据库相关知识,对mysql数据库分库分表相关知识感兴趣的朋友一起学习吧
    2016-03-03
  • 一文带你深入了解并掌握MySQL的DML和DCL

    一文带你深入了解并掌握MySQL的DML和DCL

    在数据库管理中,数据操作语言(DML)和数据控制语言(DCL)是至关重要的概念,DML使我们能够对数据库中的数据进行增加、修改和删除操作,本文将深入探讨这两个关键领域的核心概念和操作方法,帮助您更好地理解和应用数据库管理技术
    2024-02-02

最新评论