我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MYSQL数据库Innodb 引擎mvcc锁实现原理

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MYSQL数据库Innodb 引擎mvcc锁实现原理

前言:

大家都知道在java 开发过程中,会经常用到锁,在java 代码中,我们都知道锁是加在对象头上的,在java对象布局中有锁的标志位。程序通过判断锁的标志位来获取加锁的情况。但是在mysql 中,锁的实现原理是什么呢。可能大家都听过 mvcc,但是mvcc 的实现原理是什么呢,可能就说不太清楚了,本文就以实例说明来mvcc 的实现原理。

1 数据库设置隔离级别

我们都知道数据库的隔离级别可以分为以下:

  • 读未提交 RU : read uncommitted  
  • 读提交   RC : read committed 
  • 可重复读 RR : repeatable read 默认隔离级别
  • 序列化   SE : serializable 序列化

我们使用select @@transaction_isolation;来查看数据库的隔离级别,可能有读者会有疑问了,不是应该是select @@tx_isolation;吗, 因为我的电脑上装的是 mysql 8.0, 之前的 tx 也是 transaction的简写,高版本的mysql 已经使用 transaction 了。

# 查询当前会话隔离级别
select @@transaction_isolation;
# 查看当前系统的隔离级别
select @@global.transaction_isolation;
# 命令行开启事务,区别在于前者是第一条语句的执行时间点为事务开始的时间点,建立一致性读,后者是立即建立一致性读,开始执行事务
start transaction 或者 start transaction with consistent snapshot
# 设置数据库隔离级别,如若设置会话级别,则修改 global 为session 即可
set global transaction isolation level REPEATABLE READ;
set global transaction isolation level READ COMMITTED;
set global transaction isolation level READ UNCOMMITTED;
set global transaction isolation level SERIALIZABLE;

2 数据库表以及案例操作

操作的数据库表为:

CREATE TABLE `t_user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `age` int DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
# 初始化语句
INSERT INTO `t_user`(`id`, `age`) VALUES (1, 3);
# 使用的操作语句
select * from t_user where id = 1;
update t_user set age = age + 1  where id = 1;

案例如图所示:

 sessionA,sessionB,sessionC 是连接数据库的3个会话窗口,mysql 数据库的默认隔离级别为RR,为了达到效果我们把当前的数据库隔离级别改为RC,语句如下:

set session transaction isolation level READ COMMITTED;

setp1 准备工作,设置当前会话事务隔离级别,查看数据库表中的数据。窗口从左往右依次是sessionA、sessinB和sessionC。 

setp2 t1 时刻,sessionA 和 sessionB 开启事务。sessionA t2 时刻执行查询语句,sessionC 执行更新操作,可以看到此时 sessionC 立马执行成功。 

step3 t3 时刻,sessionB 查询最新的数据,并执行更新操作 

step4 t4 时刻,sessionA 查询最新数据,并在t5 时刻更新数据,这里因为sessionB 的事务还未结束,因此执行的操作会阻塞到超时(这里刻意等待到超时),t6 时刻sessionB 查询数据,并提交事务。 

step5 sesionB 提交事务后,sessionA 重新执行语句,可以看到执行后的结果,然后提交事务。 

通过上述的操作案例,我们可以观察到:

  • 在一个事务中的数据更改对本事务是可见的,此外的事务是否可见取决于其隔离级别。
  • 两个事务操作同一条数据,会造成等待。innodb 引擎默认开启死锁检测,并会设置锁的超时时间。
# 设置超时时间默认是50s
innodb_lock_wait_timeout 
# 开启死锁检测,默认是开启死锁检测,默认值为 on,开启死锁检测
innodb_deadlock_detect
# 查看更多innodb 引擎的配置
show variables like '%innodb%'
  • 在会话中进行数据修改,默认事务是自动提交的。

3 mvcc 实现原理

mvcc,Multi-Version Concurrency Control,即版本并发访问控制,是 mysql innodb 引擎实现的一种并发访问控制方法,用于其事务的实现。其主要作用是为了提高数据库的并发性能,更好地处理读写冲突问题,在遇到冲突的境况也能够做到不加锁,非阻塞并发读取数据。 在解释实现原理前,先了解一下当前读和快照读。

  • 当前读:像更改数据的操作(update/delete/insert)操作还有共享锁和排他锁(lock in share mode和for update)这操作都需要读取当前最新版本的数据,否则就会有更新丢失的情况。数据库的修改操作也是将数据所在的数据页从磁盘加载到内存,然后进行修改,最后写回到磁盘中。
  • 快照读:不加锁的select获取数据就是读快照,不会产生阻塞。在串行化的数据库隔离级别下,快照读会退化成当前度。每行数据都有多个版本,当前读就是获取最新的已经提交过得版本数据。

接下来讲述的是非常重要的部分:

  • 已经提交的事务
  • 未被提交的事务
  • 未开始的事务

在可重复读的隔离级别下,事务启动需要对整个库做备份,这显然是不可能的,实际上mvcc也没有这样做,而是利用版本号来控制,也就是事务开始时向 innodb 事务系统申请一个 transaction id,这个id申请顺序是严格递增的。每行数据的版本号 row trx_id = transaction id , 也就可以保证其版本的唯一性。可以保证事务启动时,会获取当前所有活跃事务id的数组,可以保证其唯一性。事务id数组中的最小的id记为低水位,数组中的最大id+1记为高水位。低水位和高水位便是已经提交的事务-未提交的数据、未提交的事务-未开始的事务的分界标志位,以上就组成了当前事务的一致性视图(read-view)。

前面已经提到了,所有的数据都是有版本的,这个版本即row trx_id。当需要读快照时,就需要读取trx_id小于低水位且最大的trx_id版本号的数据。读当前就是读取当前最新版本的数据,如果数据正在事务的处理中,那么久需要等待,这也是为什么会出现锁等待超时的情况。

当在RC的数据库隔离级别下,每次的操作都会重新获取当前活跃的trx_id数组,形成新的一致性视图,这就是sessionB 在t3 时刻读取到了sessionC 在t2时刻提交的数据,因为在新的一致性视图中,sessionC 的trx_id 已经已经提交的事务了,所以就可以读取到。在sessionA 的t5 时刻,拿到的一致性视图中活跃的trx_id 数组中包含 sessionB 的活跃id,因为在更新数据时,需要当前读,而数据已经被锁住,所以出现了锁超时的情况。

而在RR的数据库隔离级别下,在事务开始时生成一个一致性视图,此后在事务提交之前,其 trx_id 数组不会发生变化,这样才能保证其可重复读的特性。RR相对于RC实现简单,区别在于是否在执行语句前更新一致性视图,活跃事务id的数组是否更新。

综上,我们就知道了mvcc 是如何实现可重复读和读提交的隔离级别了。

4 ACID 的实现

  • 事务的原子性 A 是通过 undolog 回滚日志来实现。
  • 事务的持久性 C 性是通过 redolog 重做日志来实现的。
  • 事务的隔离性 I 是通过 MVCC 来实现的。
  • 原子性,持久性,隔离性都实现了,那么一致性 D 也就实现了。

redo log 是mysql innodb 引擎产生的物理日志,其大小有一定的限制,采用循环写入的方式,写满之后进行刷盘。主要用于宕机后的数据恢复。redo log是一个循环写入的日志,可以理解为一个环,有 checkpoint 和 write pos 两个标志点,checkpoint之前的空间是清除后的可写空间,清除之前会更新到磁盘中,write pos是数据写入的位置,当两个标志点相遇表明redo log已经满了,这时数据库停止进行数据库更新语句的执行,转而进行redo log日志同步到磁盘中。

binlog 是mysql server 层记录逻辑的日志,可以一致追加写入,主要用于主从数据同步。

到此这篇关于MYSQL数据库Innodb 引擎mvcc锁实现原理的文章就介绍到这了,更多相关mysql mvcc锁实现内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MYSQL数据库Innodb 引擎mvcc锁实现原理

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MySql数据库InnoDB引擎ACID的实现原理

那么数据库是如何实现这四大特性的呢? 本文以MySQL的InnoDB引擎为例,详细分析ACID四大事务特性的实现原理; 一、原子性(Atomicity),原子性的特点是一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部
MySql数据库InnoDB引擎ACID的实现原理
2015-09-05

mysql中Innodb 行锁实现原理

目录一、Innodb行锁的实现二、场景分析三、特殊场景一、Innodb行锁的实现【1】Innodb的行锁是通过给索引的索引项加锁来实现的【2】Innodb按照辅助索引进行数据操作时,辅助索引和主键索引都将锁定指定的索引项【3】通过索引
mysql中Innodb 行锁实现原理
2024-10-21

MySQL INSERT锁与数据库存储引擎选择

在MySQL中,INSERT操作会涉及到行级锁以及存储引擎的选择。行级锁:在MySQL中,插入操作会涉及到行级锁。当一个INSERT操作执行时,MySQL会在表中插入新的行,并在该行上设置一个写锁,其他事务将无法同时对这行进行修改。这样可以
MySQL INSERT锁与数据库存储引擎选择
2024-08-19

了解MySQL MVCC 原理,优化数据库事务处理

了解MySQL MVCC 原理,优化数据库事务处理近年来,随着数据量的不断增长和应用需求的提升,数据库事务处理的性能优化成为了数据库开发和运维中一个非常重要的环节。MySQL作为最常用的开源关系型数据库之一,其MVCC(Multi-Vers
2023-10-22

MySQL MyISAM默认存储引擎实现原理

默认MyISAM的表会在磁盘中产生3个文件:.frm(表结构文件)、.MYD(数据文件)、.MYI(索引文件)可以在创建的时候指定数据文件和索引文件的存储位置,只有MyISAM表支持:DATA DIRECTORY [=] 数据保存的绝对路径
2022-05-28

MySQL数据库锁的实现

本文主要介绍了MySQL数据库锁的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-20

MySQL 数据库锁的实现

目录1.什么是锁2.锁解决的问题3.并发访问相同记录的几种情况4.理解读锁和写锁4.1 读锁4.2 写锁5.表锁5.1 表级的读/写锁5.2 意向锁6.行锁6.1 记录锁6.2 间隙锁6.3 临界锁7.悲观锁和乐观锁7.1 悲观锁7.2 乐
2023-03-20

MySQL数据库锁机制原理解析

在并发访问情况下,很有可能出现不可重复读等等读现象。为了更好的应对高并发,封锁、时间戳、乐观并发控制(乐观锁)、悲观并发控制(悲观锁)都是并发控制采用的主要技术方式。 锁分类①、按操作划分:DML锁,DDL锁②、按锁的粒度划分:表级锁、行级
2022-05-21

数据库中索引的实现原理:B-tree索引

数据库会使用一些方式来存储、读取和修改数据,在实际的数据库管理中,数据库会同时使用B-tree和B+tree来存储数据。其中B-tree用于索引,B+tree用于存储实际记录。本文带来B-tree在数据库中的索引机制。B-tree即B树,它
数据库中索引的实现原理:B-tree索引
2024-01-22

MySQL数据库锁如何实现

这篇“MySQL数据库锁如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL数据库锁如何实现”文章吧。1.什么是
2023-03-23

MySQL MVCC 原理解析和应用实践:提高数据库事务处理效率

MySQL MVCC 原理解析和应用实践:提高数据库事务处理效率一、MVCC 原理解析MVCC(Multi-Version Concurrency Control)是MySQL中实现并发控制的一种机制。它通过记录行的历史版本来实现并发事务的
2023-10-22

编程热搜

目录