【MySQL】事务的隔离级别是如何实现的
水稻: 菜瓜,听说最近你在复习MySQL方面的知识,想请教一下MySQL的事务?
菜瓜:嗯,最近刚刚看到。事务指的是MySQL中不可拆分的业务单元,具有ACID的属性。
水稻: ACID我知道啊,但是不太懂他的实现,你能说和我聊聊事务在数据库底层是怎么实现的吗?
菜瓜:据我了解,不同的特性底层的实现不一样,主要依赖两种日志和锁来实现
- 先说持久性:我们知道数据的操作会先在内存中完成,那么事务提交后如何保证一定能持久化到磁盘呢
- redo log: 事务在提交前对数据的修改会先写到redo log 中,如果返回事务已提交成功,那么表示redo log已经记录完成。redo log 也有缓冲区,redo log的内存缓冲区大小和磁盘扇区的大小512字节一致,不会出现掉电易失的情况。另外redo log记录的是物理变化,体积很小,且redo log 写磁盘是顺序IO,极快~丝滑
- redo log 和binlog区别:一个是用于做持久化,另一个用作数据恢复和复制
- 原子性,指的是被事务包裹的一组操作要么全部成功,要么全部失败。不会存在执行了一部分,另一部分不执行的情况
- undo log: MySQL使用undo log实现操作回滚。事务开启后执行的命令都会有一条对应反向的逻辑日志计入undo日志文件中(譬如insert 就会有一条delete)。undo log的持久化会被记录在redo log中(利用redo log 速度快的特性)。一旦发生错误或者回滚的时候,利用undo就可以操作回去
水稻: 那还有一致性和隔离性呢?
菜瓜:一致性和隔离性可以放在一起说,隔离级别的选择就是一致性和隔离性的权衡
- 实现多个事务之间的隔离。一种是锁,另一种是mvcc机制。
水稻:锁我知道,mvcc是什么?
菜瓜:我们把数据库的读操作分为两类,一是当前读,使用锁机制;一是快照读,使用mvcc
- 当前读
- 数据的修改操作(insert update delete)和查询时显示加锁 select(查询条件后加上 lock in share mode & for update)
- 会锁住要读取的数据以保障数据的一致
- 快照读 使用的是mvcc机制,就是多版本并发控制。
- 除当前读之外,普通的select查询为快照读,顾名思义,就是读取的是一个快照版本,以隔离多个事务之间的数据
水稻:能不能仔细说说这个mvcc
菜瓜:可以,它的实现还是依赖undo log来做的
- 在RR RC两种级别下使用。其他两种不需要实现隔离
- 你肯定听说过mysql在RR级别下解决了幻读问题,就是依赖这个来做的
- 简单来说就是,MySQL维护了一个记录活跃事务id的列表readview
- undo log是怎么记录的呢。举个栗子
- innodb的表中存在三个额外的隐藏字段,分别是编辑该条记录的事务id,更改前的undo log的回滚指针,还有一个对我们这个分析不太重要
- 如果有事务对该记录做了变更,事务id会更新,同时undo log里面会产生新记录,回滚指针字段指向最新的undo log链
- 通过比较当前事务id和readview中其他事务的id大小来决定自己读取的数据是哪个版本的undo log记录
- 如果当前事务id比readview中的都小,就说明该条记录没有被其他事务更改。直接读取
- 如果当前事务id比readview中的都大,沿着undo log链能找到最小事务id指向的undo log,该数据为稳定数据
- RR级别下利用该机制避免了幻读
- RC级别下每次都会读取数据的最新记录
总结:
- 事务的持久性和原子性由Redo log和Undo log实现
- 隔离性和一致性的权衡由锁机制和MVCC实现
部分内容为自己猜想,如有错误,欢迎指正!
参考文章
- MySql-Undo及Redo详解 https://blog.csdn.net/aaa821/article/details/80645242
- MySql MVCC 多版本并发控制 https://www.cnblogs.com/paulwang92115/p/12189487.html
【MySQL】事务的隔离级别是如何实现的的更多相关文章
- 事务的隔离级别,mysql默认的隔离级别是什么?
读未提交(Read uncommitted),一个事务可以读取另一个未提交事务的数据,最低级别,任何情况都无法保证. (1)所有事务都可以看到其他未提交事务的执行结果 (2)本隔离级别很少用于实际应用 ...
- MySQL事务学习-->隔离级别
MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...
- MYSQL事务和锁
mysql事务(一)—转载 2012年12月20日 ⁄ Mysql数据库, 技术交流 ⁄ 暂无评论 一. 什么是事务 事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子) ,不可分割 ...
- MySQL(十三)之MySQL事务
前言 这段时间自己会把之前学的东西都总结一遍,希望对自己以后的工作中有帮助.其实现在每天的状态都是很累的,但是我要坚持! 进入我们今天的正题: 为什么MySQL要 有事务呢?事务到底是用来干什么的?我 ...
- MySQL事务与锁
MySQL事务与锁 锁的基本概念 锁是计算机协调多个进程或线程并发访问某一资源的机制. 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISA ...
- MySQL事务以及隔离级别
前言: 我一直想不到一个好的标题应该怎么写.我想MySQL的一些重要的内容.我在两次面试中都遇到过的,但直接用MySQL标题好像又不太贴切.干脆就是所写的内容吧. MySQL事务: transacti ...
- MySQL事务的的介绍及使用
事务的特性 1.原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生. 2.一致性(Consistency):在一个事务中,事务前后数据的完整性必 ...
- mysql事务隔离级别详解和实战
A事务做了操作 没有提交 对B事务来说 就等于没做 获取的都是之前的数据 但是 在A事务中查询的话 查到的都是操作之后的数据 没有提交的数据只有自己看得到,并没有update到数据库. 查看InnoD ...
- 深入学习MySQL事务:ACID特性的实现原理
事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段.本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理. MySQL博大精深,文 ...
- 一文说尽MySQL事务及ACID特性的实现原理
MySQL 事务基础概念 事务(Transaction)是访问和更新数据库的程序执行单元:事务中可能包含一个或多个 sql 语句,这些语句要么都执行,要么都不执行.作为一个关系型数据库,MySQL 支 ...
随机推荐
- JVM知识总结-01
1 程序计数器 程序计数寄存器(Program Counter Register),是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工作时就是 ...
- 张高兴的大模型开发实战:(六)在 LangGraph 中使用 MCP 协议
目录 什么是 MCP 协议 MCP 协议与 API 调用的区别 MCP 协议的连接方式 SSE(Server-Sent Events) stdio(标准输入输出) 在 LangGraph 中使用 MC ...
- 基于 SSE、asp.net core razor 实现比分Live
前言 最近在项目中用到了 SSE (Server-Sent Events),用于服务的单向长连接数据推送.因为都是使用 C# 实现的,所以服务端使用的是 HttpListener ,而客户端更简单,只 ...
- MySQL SQL语句书写顺序和执行顺序
目录 SQL语句书写顺序和执行顺序 MySql执行顺序理解 实例 知识扩展 on和where的区别 limit 分页 结束语 Reference SQL语句书写顺序和执行顺序 (7) SELECT ( ...
- Web前端入门第 65 问:JavaScript 函数参数各种使用方式
函数参数是什么? 就是函数内部无法确定的一个东西,需要外部传给函数内部的玩意儿,语法上就是写在函数括号中的东东.比如: function test(a) {} 其中的 a 就是 test 函数的参数, ...
- 常用Dockerfile注意事项
Dockerfile添加PATH生效 # 注意不要写= ENV CONDA_DIR /opt/anaconda3 ENV PATH $CONDA_DIR/bin:$PATH Dockerfile添加普 ...
- Tcode:PFAL说明
Short text HR: ALE Distribution of HR Master Data Description. Scenario 1: Distribution of HR Master ...
- 数栈技术分享:详解FlinkX中的断点续传和实时采集
数栈是云原生-站式数据中台PaaS,我们在github和gitee上有一个有趣的开源项目:FlinkX,FlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,也可以采集实时变 ...
- 网络编程TCP UDP
网络编程 (1)什么是网络编程 网络编程是指通过编程语言在计算机之间建立通信的一种方式. 它是在互联网上进行数据传输的关键组成部分,使计算机能够相互通信.交换信息和共享资源. 网络编程涉及许多不同的技 ...
- 解决Dev c++6版本中文输出乱码问题
解决Dev c++6.3版本中文输出乱码问题 1.遇到的问题 使用cout输出中文时出现乱码问题 如下图所示: 2.解决方法 找到[工具]--[编译选项]--勾选[编译时加入以下命令]并添加如下代码: ...