深入浅出MySQL事务实现底层原理

重要概念

事务的ACID

  • 原子性(Atomicity):即不可分割性,事务中的操作要么全不做,要么全做
  • 一致性(Consistency):一个事务在执行前后,数据库都必须处于正确的状态,满足完整性约束
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
  • 持久性(Durability):事务处理完成后,对数据的修改就是永久的,即便系统故障也不会丢失

脏读、幻读、不可重复读

  • 脏读,读取了未提交的数据
  • 不可重复读,事务A期间读取多次b,b被其他事务影响,导致值不可重复
  • 幻读,幻读和不可重复读有点像,它是事务A期间统计多次同一批数据,统计结果不一样。原因是被其他事务影响。它们的区别主要在于前者读取精确的某几条数据,后者则是范围统计——多版本不好控制

主从复制的原理

  • 主数据库有个bin log记录了所有sql语句
  • 把主数据库的bin log的语句复制到从数据库
  • 从数据库在relay log重做日志中再执行一遍这些sql

具体而言,
在这里插入图片描述

  • 主数据库启用输出线程,输出bin log
  • 从数据库IO线程,负责从主数据库里拉取bin log,写入到relay log
  • sql线程,将relay log重做

三大日志

bin log、redo log和undo log

bin log是归档日志,用于主从复制、数据备份等。
redo log是重做日志,用于实现事务持久性。在事务在提交时断电重启后,可以正常从中恢复。
undo log为回滚日志,用于实现事务的原子性,即当事务失败时,可以全部操作都取消。

bin log和undo log都是MySQL里边服务层的概念,它记录的是逻辑记录,例如完成了什么SQL。而redo log是存储层的物理操作日志,例如“在某个数据页上做了更改”。
在执行更新语句过程,会记录 redo log 与 binlog 两块日志,以基本的事务为单位,redo log 在事务执行过程中可以不断写入,而 binlog 只有在提交事务时才写入,所以 redo log 与 binlog 的写入时机不一样。

buffer与同步

既然是日志,那就躲不开缓存和落盘策略,这当然也是很通用的一些解决实践。这里以redo log为例:
在这里插入图片描述

落盘时机,可以通过配置来指定:

  • 0,事务提交不落盘,根据异步同步线程的时间来定(通常是1s)
  • 1,每次事务提交都落盘
  • 2,写入pagecache,介于0和1之间

日志提交的事务

在进行数据库操作的时候,需要同时操作多个日志,这个时候如何保证事务性呢?例如,宕机之后,如何确保binlog和redo log的数据是一致的?
这和[[分布式事务]]做的事情基本是一样的。MySql中采用两阶段进行日志的事务提交。
在这里插入图片描述

将redo log拆成两个阶段,最终提交阶段在binlog完成之后再提交。故障恢复的时候,不管在什么阶段,一切认准binlog的提交记录。即使在redolog commit期间出错,那么只要binlog落库成功,说明redolog一定parepare完成,可以恢复提交。

这又侧面印证了一个想法:分布式事务,其实本质上是把一件很大的、多阶段的过程,拆解,细分,尽可能把最终这个影响数据一致的过程缩小到最小粒度,尽管无法完全消除,尽可能减少出错的可能性。例如上述例子,就是把耗时的redolog写入过程拆出去,缩小到最终redo log的提交这个更短、更细粒度的过程上。

MVCC如何实现

copy on write

MVCC其实体现的是copy on write的一种思想——追求数据不变性,那么就直接复制一份快照。
数据库这么大的数据量,当然不可能是真的复制一整个库、一整个表,只需要复制相应的行就可以了。那么MySQL到底是怎么实现的呢?
这是必然是一个非常复杂的机制,涉及到并发SQL复杂操作、多版本数据、各个事务之间实时的可见性管控。
核心的有两点:
数据库通过两个核心隐藏列来完成多版本记录:

  • DB_TRX_ID,当前事务ID。单调递增,因而可以通过大小确定当前事务和其他事务的可见性——对比事务ID大小即可。例如,事务ID小于它的就可见,大于它的就不可见。你可以理解,这个就是版本。
  • DB_ROLL_PTR。回滚指针,指向对应的redo log记录。上边记录了“版本号”,那么,我们就会好奇,copy on write中的精髓,copy又是怎么体现的呢?答案就是,通过回滚指针。它不会直接复制一行出来,而会在原行上边修改,如果需要找到上一个版本,就通过回滚指针找到redo log,从而找到上一个版本。

从插入和更新来分析实际分析一下:
insert,由于是新增数据,所以不需要redo log指针,只需要记录事务id。
在这里插入图片描述

update,更上边分析一样,除了记录事务ID还得记录回滚指针。
在这里插入图片描述

第二次修改,这里重点来了,多版本如何copy呢?答案是拉链:
在这里插入图片描述

可见性保证

事务之间可见性的如何保证,这个也是一大难题。
大致描述一下我的理解:MySQL在开启事务的时候,会收集当前活跃的事务列表,于是它就可以通过事务ID,加上上边的多版本数据,去分析当前存在的数据变更,自己可见的是哪些,不可见的是哪些。
下边是当前可视视图的声明。

class ReadView {
private:trx_id_t m_low_limit_id;      /* 目前出现最大的事务ID,大于等于这个 ID 的事务均不可见 */trx_id_t m_up_limit_id;       /* 小于这个 ID 的事务均可见 */trx_id_t m_creator_trx_id;    /* 创建该 Read View 的事务ID */trx_id_t m_low_limit_no;      /* 事务 Number, 小于该 Number 的 Undo Logs 均可以被 Purge */ids_t m_ids;                  /* 创建 Read View 时的活跃事务列表 */m_closed;                     /* 标记 Read View 是否 close */
}

处于最大、最小ID之间的,就是活跃但不可见的事务列表。
在这里插入图片描述

事务的实现

好了,这下我们有充足的知识可以来讨论如何实现事务了。

整体方案

  • 原子性,undo log,事务中断恢复
  • 持久性,redo log,同步写回磁盘,提交断电时可恢复
  • 隔离性,通过读写锁和MVCC来实现的
  • 一致性,通过上述三者来实现的。

隔离性,对应四种隔离级别

READ UNCOMMITTED

在这里插入图片描述

读不加锁,不排斥写。

  • 优点:读写并行,性能高
  • 缺点:造成脏读

READ COMITTED

在这里插入图片描述

读不加锁,读写分离。但这里MVCC的方式,是每次读的时候,都会读取不同版本,这会造成不可重复读问题。

当然,也有幻读问题。

REPEATABLE READ(Mysql默认隔离级别)

最简单的方式,读写锁实现,让读写串行:

在这里插入图片描述

  • 优点:实现起来简单
  • 缺点:无法做到读写并行

MVCC

在这里插入图片描述

通过版本控制,解决版本不同问题产生不可重复读的问题

  • 优点:读写并行
  • 缺点:实现的复杂度高,依然存在幻读的问题

InnoDB是可以解决幻读的,大致的思想也很简单, Next-key Lock对查询间隙进行加锁,不让插入自然也就不会有幻读问题。

SERIALIZABLE

在这里插入图片描述

注:
可线性化和可串行化,听起来很像,感觉也很像。其实不太一样,两者是分布式数据库中的一致性模型,但后者主要指事务中的一种隔离级别。
我的理解是,最大的区别在于,可线性化要求对于所有事件,都必须满足所有时刻的先后可见性。而可序列化仅需要保证多个并行的事务和某个事务序列结果一致即可。
这非常像Java中重排和happen-before的理念。

参考

  1. https://blog.csdn.net/weixin_36380516/article/details/107572412
  2. https://javaguide.cn/database/mysql/innodb-implementation-of-mvcc.html#readview

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/16423.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java开发大厂面试第17讲:MySQL 的优化方案有哪些?数据库设计、查询优化、索引优化、硬件和配置优化等

性能优化(Optimize)指的是在保证系统正确性的前提下,能够更快速响应请求的一种手段。而且有些性能问题,比如慢查询等,如果积累到一定的程度或者是遇到急速上升的并发请求之后,会导致严重的后果,…

变分自动编码器(VAE)深入理解与总结

本文导航 0 引言1 起源1.1 自编码器的任务定义1.2 自编码器存在的问题1.3 VAE的核心思路 2 VAE的建模过程2.1 VAE的任务定义2.2 真实分布 ϕ \phi ϕ是什么,为什么要逼近这个分布的参数,如何做?2.3 “重参数化(Reparameterization…

互联网十万个为什么之 什么是Kubernetes(K8s)?

Kubernetes(通常简称为K8s)是一款用于自动部署、扩缩和管理容器化应用程序的开源容器编排平台。Kubernetes已发展为现代企业实现敏捷开发、快速迭代、资源优化及灵活扩展的关键技术组件之一。它拥有庞大的开源社区和丰富的生态系统。围绕Kubernetes已经形…

.lib .a .dll库互转

编译 mingw工具,gendef.exe转换dll为a,reimp转换lib为adlltool.exe --dllname python38.dll --def python38.def --output-lib libpython38.adlltool -k -d crypto.lib -l crypto.a 创作不易, 小小的支持一下吧!

QT之常用控件

一个图形化界面当然需要有各种各样的控件,QT也不例外,在QT designer中就有提供各种各样的控件,用以开发图形化界面。 而想使用好一个QT控件,就需要了解这些控件。 QWidget 在QT中,所有控件都继承自 QWidget 类&…

推荐10款优秀的组件库(一)

1.Ant Desgin UI 网址: https://ant-design-mobile.antgroup.com/zh Ant Design - 一套企业级 UI 设计语言和 React 组件库 "Ant Design Mobile"是一个在线的移动端Web体验平台,让你探索移动端Web的体验极限。 添加图片注释,不…

622.设计循环队列

typedef struct {int* a;int head;int tail;int k; } MyCircularQueue;bool myCircularQueueIsEmpty(MyCircularQueue* obj); bool myCircularQueueIsFull(MyCircularQueue* obj);//初始化 MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj(MyCircularQue…

探索python列表处理:偶数筛选的两种方法

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言 二、不使用列表生成式的偶数筛选 1. 读取输入列表 2. 筛选偶数 三、使用列表生…

重学java 46.集合 ① Collection集合

事常与人违,事总在人为 —— 24.5.26 集合 知识导航 1.集合的特点以及作用 2.使用collection接口中的方法 3.使用迭代器迭代集合 4.ArrayList以及LinkedList的使用 5.使用增强for遍历集合 一、单列集合框架的介绍 1.长度可变的容器:集合 2.集合的特点 a.…

每日一问-如何设置VS Code 中 Markdown粘贴图片的位置

VS Code内的markdown编辑器应该算是比较好用的,但是有一个问题一直困扰着我,就是在编辑markdown文件时,粘贴图片的位置问题。默认情况下,VS Code会将粘贴的图片放在markdown文件的同级目录下,这样会导致markdown文件的…

OSPF多区域组网实验(华为)

思科设备参考:OSPF多区域组网实验(思科) 技术简介 OSPF多区域功能通过划分网络为多个逻辑区域来提高网络的可扩展性和管理性能。每个区域内部运行独立的SPF计算,而区域之间通过区域边界路由器进行路由信息交换。这种划分策略适用…

构建智慧科技园区的系统架构:数字化驱动未来创新

随着科技的不断进步和数字化转型的加速推进,智慧科技园区已成为当今城市发展的重要组成部分。在智慧科技园区建设中,系统架构的设计和实施至关重要,对于提升园区管理效率、优化资源利用、促进创新发展具有重要意义。 一、智慧科技园区系统架构…

02.并发编程基础概念

在正式学习 Java 的并发编程之前,我们需要熟悉和学习几个并发编程的基础概念。 1 进程和线程 1.1 进程 我们常说的是应用程序,也就是 app,由指令和数据组成。但是当我们不运行一个具体的 app 时,这些应用程序就是放在磁盘(也包括…

化学中的不确定性。

化学中的不确定性TOC 基于元素分析的无机化学的理论大厦应该说早已落成了,但是却仍然存在着一些列的难解甚至是无解问题,这些大多是在使用理论解释现象时遇到的困难,有些则是在生产实践中生产工艺和生产工序设计和优化中发现的问题。于是&…

基于PID的单片机温度控制系统设计

基于PID的温度控制系统设计 摘要 温度是工业上最基本的参数,与人们的生活紧密相关,实时测量温度在工业生产中越来越受到重视,离不开温度测量所带来的好处,因此研究控制和测量温度具有及其重要的意义。 本设计介绍了以AT89C52单片…

JavaWeb_Web——Maven

介绍: Maven是Apache公司发行的,一个Java项目管理和构建工具 作用: 1.方便的依赖管理 2.统一的项目结构 3.标准的项目构建流程 模型: Maven通过项目对象模型(POM)和依赖管理模型(Dependency)管理依赖(jar包),如果新添…

DEM、DSM和DTM之间的区别及5米高程数据获取

在日常的学习工作中我们经常会遇到DEM、DSM和DTM等术语,它们的含义类似,甚至相互替换。那么它们之间有什么区别?这里我们对这些术语进行介绍。 DEM(数字高程模型,Digital Elevation Model): 定义…

贪心-AcWing 125. 耍杂技的牛-XMUOJ蒙德冒险者的游戏

题目 思路 每头牛的危险值 他前面牛的w(重量值)之和 - 自身的s(强壮值) 要使每头牛的危险值最小,根据贪心思想: 自身w值越大应该放到底部(即减小上述式中的被减数) 自身s值越大应该放到底部(即增大上述式中的减数&…

【Spring】深入理解 Spring Web 应用程序初始化流程

前言 在构建基于 Spring 的 Web 应用程序时,了解初始化流程是至关重要的。本文将详细介绍 Servlet 容器的初始化过程,并重点探讨 Spring 框架在其中的作用,特别是 ServletContainerInitializer、SpringServletContainerInitializer 和 WebAp…

使用AWR对电路进行交流仿真---以整流器仿真为例

使用AWR对电路进行交流仿真—以整流器仿真为例 生活不易,喵喵叹气。马上就要上班了,公司的ADS的版权紧缺,主要用的软件都是NI 的AWR,只能趁着现在没事做先学习一下子了,希望不要裁我。 本AWR专栏只是学习的小小记录而…