当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL InnoDB锁的分类和使用情况分析

MySQL InnoDB锁的分类和使用情况分析

来源:亿速云 2023-04-28 20:11:42 0浏览 收藏

目前golang学习网上已经有很多关于数据库的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《MySQL InnoDB锁的分类和使用情况分析》,也希望能帮助到大家,如果阅读完后真的对你学习数据库有帮助,欢迎动动手指,评论留言并分享~

MySQL InnoDB锁的分类和使用情况分析

mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.7.21    |
+-----------+
1 row in set (0.01 sec)

一,锁的基本介绍

相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

行级锁类型:

Record Lock(记录锁):当个记录的锁(锁住单条记录)

记录锁只会锁住索引的记录,如果InnoDB存储表在建立的时候没有任何索引,那么这个锁会使用隐式的主键来进行锁定,如下图

MySQL InnoDB锁的分类和使用情况分析

Gap Lock(间隙锁):锁定一个范围,不包括记录本身(只锁数据前面的GAP)

如下图为的锁就是GAP锁,就是不允许其他事务在索引列8之前的间隙插入新的记录,也就是(3 , 8)这个区间。gap锁 的作用仅仅是为了防止插入幻影记录的而已

MySQL InnoDB锁的分类和使用情况分析

Next-Key Lock(临键锁):同时锁住记录和记录前面的GAP,也就是Next-Key Lock = Record Lock + Gap Lock。

MySQL InnoDB锁的分类和使用情况分析

二,锁的分类

共享锁 Share Locks (简称S锁,属于行锁)

排它锁 Exclusive Locks (简称X锁,属于行锁)

意向共享锁 Intention Share Locks (简称IS锁,属于表锁)

意向排它锁 Intention Exclusive Locks (简称IX锁,属于表锁)

自增锁 AUTO-INC Locks(属于表锁)

下面具体介绍下每种类型的锁,我们先建一张innodb的表,sql如下

create table tab_with_index(id int,name varchar(10)) engine=innodb;
alter table tab_with_index add index id(id);
insert into tab_with_index values(1,'1'),(2,'2'),(3,'3'),(4,'4');
共享锁

共享锁就是多个事务对于同一个数据可以共享一把锁,都能访问数据库,但是只能读不能修改;

事务A:

select * from tab_with_index lock in share mode;

事务B:

select * from tab_with_index where id =1; // 可以查询数据

update tab_with_index set name = 'aa' where id = 1 ;

注意:这里的修改语句会堵塞住,直到事务A提交之后才能操作成功。

排它锁

排它锁不能与其他锁并存,如一个事务获取了一个数据行的排它锁,其他事务就不能在获取该行的锁,只有当前获取排它锁的事务可以对数据进行修改。(delete,update,create默认是排它锁)

事务A:

select * from tab_with_index where id =1 for update;

事务B:

select * from tab_with_index where id =1; //可以获取结果

select * from tab_with_index where id =1 for update; // 堵塞

select * from tab_with_index where id = 1 lock for share mode; // 堵塞

注意:事务B两个sql都会堵塞住,也就是获取不到共享锁也获取不到排它锁,直到事务A提交之后才能操作成功。

意向共享锁和意向排它锁

意向共享锁:表示事务准备给数据行加入共享锁,也就是说一个数据行在加共享锁之前必须先获取该表的IS锁。

意向排它锁:表示事务准备给数据行加入排它锁,也就是说一个数据行加排它锁之前必须先获取该表的IX锁。

IS锁和IX锁是表级锁,他们的提出仅仅为了在之后加表级别的S锁和X锁时可以快速判断表中的记录是否被上锁,以避免用遍历的方式来查看表中有没有上锁的记录,也就是说其实IS锁和IX锁是兼容的,IX锁和IX锁是兼容的。 《MySQL是怎样运行的》

自增锁

针对自增列自增长的一个特殊的表级别锁。

show variables like 'innodb_autoinc_lock_mode'; 
-- 默认值1,代表连续,事务未提交则ID永久丢失

MySQL InnoDB锁的分类和使用情况分析

三,InnoDB锁

1、事务及其ACID属性

事务是由一组SQL语句组成的逻辑处理单元,事务具有4属性,通常称为事务的ACID属性。

原子性(Actomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。 一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。 隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。 持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

2、并发事务带来的问题

相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多用户的并发操作,但与此同时,会带来一下问题:

脏读: 一个事务正在对一条记录做修改,在这个事务并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”的数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做“脏读”

不可重复读:一个事务在读取某些数据已经发生了改变、或某些记录已经被删除了!这种现象叫做“不可重复读”。

幻读: 一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”

上述出现的问题都是数据库读一致性的问题,可以通过事务的隔离机制来进行保证。

数据库的事务隔离越严格,并发副作用就越小,但付出的代价也就越大,因为事务隔离本质上就是使事务在一定程度上串行化,需要根据具体的业务需求来决定使用哪种隔离级别


脏读不可重复读幻读
read uncommitted
read committed
repeatable read

serializable


可以通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况:

mysql> show status like 'innodb_row_lock%';
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| Innodb_row_lock_current_waits | 0     |
| Innodb_row_lock_time          | 18702 |
| Innodb_row_lock_time_avg      | 18702 |
| Innodb_row_lock_time_max      | 18702 |
| Innodb_row_lock_waits         | 1     |
+-------------------------------+-------+
--如果发现锁争用比较严重,如InnoDB_row_lock_waits和InnoDB_row_lock_time_avg的值比较高

3、InnoDB的行锁模式及加锁方法

共享锁(S) :又称读锁(lock in share mode)。允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。  排他锁(X) :又称写锁(for update)。允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。

mysql InnoDB引擎默认的修改数据语句:update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务中是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。

4、InnoDB行锁实现方式

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

1、在不通过索引条件查询的时候,innodb使用的是表锁而不是行锁

create table tab_no_index(id int,name varchar(10)) engine=innodb;
insert into tab_no_index values(1,'1'),(2,'2'),(3,'3'),(4,'4');
session1session2
set autocommit=0 select * from tab_no_index where id = 1;set autocommit=0 select * from tab_no_index where id =2
select * from tab_no_index where id = 1 for update

select * from tab_no_index where id = 2 for update;

session1只给一行加了排他锁,但是session2在请求其他行的排他锁的时候,会出现锁等待。原因是在没有索引的情况下,innodb只能使用表锁。

2、创建带索引的表进行条件查询,innodb使用的是行锁

create table tab_with_index(id int,name varchar(10)) engine=innodb;
alter table tab_with_index add index id(id);
insert into tab_with_index values(1,'1'),(2,'2'),(3,'3'),(4,'4');
session1session2
set autocommit=0 select * from tab_with_indexwhere id = 1;set autocommit=0 select * from tab_with_indexwhere id =2
select * from tab_with_indexwhere id = 1 for update

select * from tab_with_indexwhere id = 2 for update;

3、由于mysql的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是依然无法访问到具体的数据(这里是表锁)

alter table tab_with_index drop index id;
insert into tab_with_index  values(1,'4');
session1session2
set autocommit=0set autocommit=0
select * from tab_with_index where id = 1 and name='1' for update

select * from tab_with_index where id = 1 and name='4' for update 虽然session2访问的是和session1不同的记录,但是锁的是具体表,所以需要等待锁

终于介绍完啦!小伙伴们,这篇关于《MySQL InnoDB锁的分类和使用情况分析》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布数据库相关知识,快来关注吧!

版本声明
本文转载于:亿速云 如有侵犯,请联系study_golang@163.com删除
优化 Windows 11 游戏性能的 7 个设置教程优化 Windows 11 游戏性能的 7 个设置教程
上一篇
优化 Windows 11 游戏性能的 7 个设置教程
马斯克称开发新人工智能是为了深入理解宇宙本质
下一篇
马斯克称开发新人工智能是为了深入理解宇宙本质
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    514次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    499次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • SEO  AI Mermaid 流程图:自然语言生成,文本驱动可视化创作
    AI Mermaid流程图
    SEO AI Mermaid 流程图工具:基于 Mermaid 语法,AI 辅助,自然语言生成流程图,提升可视化创作效率,适用于开发者、产品经理、教育工作者。
    239次使用
  • 搜获客笔记生成器:小红书医美爆款内容AI创作神器
    搜获客【笔记生成器】
    搜获客笔记生成器,国内首个聚焦小红书医美垂类的AI文案工具。1500万爆款文案库,行业专属算法,助您高效创作合规、引流的医美笔记,提升运营效率,引爆小红书流量!
    209次使用
  • iTerms:一站式法律AI工作台,智能合同审查起草与法律问答专家
    iTerms
    iTerms是一款专业的一站式法律AI工作台,提供AI合同审查、AI合同起草及AI法律问答服务。通过智能问答、深度思考与联网检索,助您高效检索法律法规与司法判例,告别传统模板,实现合同一键起草与在线编辑,大幅提升法律事务处理效率。
    244次使用
  • TokenPony:AI大模型API聚合平台,一站式接入,高效稳定高性价比
    TokenPony
    TokenPony是讯盟科技旗下的AI大模型聚合API平台。通过统一接口接入DeepSeek、Kimi、Qwen等主流模型,支持1024K超长上下文,实现零配置、免部署、极速响应与高性价比的AI应用开发,助力专业用户轻松构建智能服务。
    204次使用
  • 迅捷AIPPT:AI智能PPT生成器,高效制作专业演示文稿
    迅捷AIPPT
    迅捷AIPPT是一款高效AI智能PPT生成软件,一键智能生成精美演示文稿。内置海量专业模板、多样风格,支持自定义大纲,助您轻松制作高质量PPT,大幅节省时间。
    231次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码