请你来了解一下Mysql-InnoDB中事务的两段式提交

欢迎订阅专栏,了解更多Mysql的硬核知识点,原创不易,求打赏

ACID:事务的四个特性

A:原子性

原子性表示把一个事务中所有的操作视为一个整体,要么全部成功,要么全部失败,是事务模型区别文件系统的重要特征之一

C:一致性

官方对一致性的解释为事务将数据库从一种状态转变为下一种一致性状态,在事务开始之前和食物结束以后,数据库的完整性约束没有被破坏。

而我对一致性的理解为事务的执行可以让各方在指定规则下都认可这个事务产生的变更。比如事务提交后将数据写入binlog,事务提交后redo会写入prepare,commit状态的数据,undo会维护该版本的数据,数据写入(聚集,非聚集)索引表等等。

就好像DDD中的限界上下文一样,大家对于这个领域的边界有共同且明确的认知

InnoDB事务的两段式提交中,主要就是对原子性和一致性的保证。

I:隔离性

隔离性基本的理解是事务之间不会互相干扰。但这是结果。通过什么方式可以使得事务的执行不会互相干扰呢?

如果数据库只允许串行化执行事务,那么就没有隔离性什么事,但是现在的社会,连人类都得加班,互卷,为了让自己的业绩,考核能够更好。对于数据库来说,不可能让一个数据库慢慢悠悠的执行事务,支持并发事务执行是必须的也是基本的职能(功能)。

因此系统必须支持事务的并发执行,事务的并发执行为了保证“线程安全”,必须通过一些手段让其操作在一定的限界内,不能让它们逾越法则。

所以就有了并发控制,锁的出现,通过并发控制,可以让相应的可读数据划分边界,对于不可读的内容做了屏蔽。通过锁,可以让对于同样数据的多个并发修改得以强制性串行执行。

D:持久性

需要注意的是持久性并不能保证机器物理级别的损坏(包括很多方便)或者山崩地裂导致服务器沉入大海后还要做数据恢复。针对这种情况还需要一些高可用的架构来辅助完成。

持久性保证的除了上面说的几种情况外,只要事务单方面确认提交了,那么就能够通过一些手段来恢复。

事务提交的过程图

d8d0f363cbb94d33b51661d48215b082.png

过程解释

其两段式提交主要就是在redo.log的两次prepare状态和commit状态。但是记住,并不是只有最后commit状态写入了才能恢复

假如redo.log中写入了prepare状态的数据,并且bin.log也写入了。但是写redo.log的commit状态的数据时丢失了,这时候还是可以恢复的。(那为什么不能只根据bin.log是否写入来判断事务成功,为什么还要有一个redo.log来增加复杂度呢?

因为bin.log太大了,如果系统恢复是通过bin.log来恢复,首先功能是没问题的,但是恢复的时间会很长。而redo.log很小啊(默认情况下只有48M),只需要遍历redo.log里面的数据,如果是commit状态的那么直接恢复。如果是prepare状态的,那么看一下bin.log有没有,有就恢复,没有就不恢复。

事务执行的效率

事务执行的效率除了受限于事务的大小等因素以外,还受限于磁盘的性能,为什么这么说呢?

因为默认情况下,每次都必须等到数据写入磁盘才表示事务提交成功,要不然中间如果出现问题,导致数据并没有写入redo.log或者bin.log,直接返回状态,那么必然有数据不一致性问题。

innodb控制这个过程是通过innodb_flush_log_at_trx_commit参数控制的。

0:每次事务提交的内容不写入文件,而是由master thread进行。master thread中每秒都会执行一次fsync操作

1(默认值)每次事务提交的内容必须执行一次fsync刷到磁盘,才会标记事务为成功。

2:每次事务提交的内容只写入文件系统的缓存,不进行fsync操作。

文件系统的缓存中数据写入文件几乎依赖的是操作系统的一些机制了

  • 脏数据回写策略:当文件系统缓存中的数据被修改后,会被标记为"脏"数据(dirty data)。文件系统会定期或在内存压力紧张的情况下(内核调度策略),将这些"脏"数据异步写入文件。

  • 超过内核参数设置的阈值:Linux内核有一些参数可以控制文件系统的回写行为,例如dirty_ratiodirty_background_ratio。当"脏"数据占用内存的比例超过dirty_ratio或超过dirty_background_ratio时,内核会触发异步回写操作。

  • 内核定期回写:内核中有一个脏数据回写线程 (pdflush 或 bdflush),它会定期(默认30秒)检查文件系统的缓存,将脏数据异步写入文件。

需要注意的是master thread执行fsync是固定有的功能,和事务本身的fsync并不互斥的。也就是说有时候不等本事物执行fsync,就已经让master执行了,并且master thread是每个表空间特有的线程,因此如果某个表有单独的表空间,那么其事务提交就完全靠它自己了

无论是0还是2,都不具备事务特性中的一致性,因为数据的提交变的不可预知

bin.log和redo.log的数据顺序一致吗?

那有一个问题了,bin.log和redo.log的写入顺序是不是就是一致的呢?是不是下面的这种呢

d80504382b514ec8beeec5a53dad4377.png

其实并不是,因为bin.log的写入是在事务完成后一次性写入的,而redo.log可能在事务执行过程中不断地写入

有可能是下面的这种顺序

c870084d5c10453f90557ad422510ce3.png

bin.log和redo.log 的数据格式一样吗? 

bin.log全程是binary log,记录的是对应的sql语句,是一个二进制文件

redo.log是一个物理格式数据,记录的是对每一个页的修改

延伸

redo.log的结构

redo.log的大小默认是48M,并且是由一个个redo log block组成的。一个redo log block的大小是512字节,所以默认情况下总有48MB / 512B = 98304个redo log block。

有没有发现redo log block的512字节的大小和磁盘扇区的大小是一样的,所以对于redo log block来说是可以保证原子性的,不需要doublewrite技术

5102ec1351ed4e8e9afcf1217a3d4970.png

一个redo log block最多可以存储492字节的数据,如果超过了492字节,就会被分配到下一个redo log block。那如果有多条日志都很小,比如10个字节,那么一个redo log block会包含多条日志,那怎么区分每个日志的初始位置呢?

通过LSN可以记录每个页写入重做日志时的LSN的大小。前面说过重做日志记录的是对页的修改,所以在页的数据结构中也有FIL_PAGE_LSN来记录该页的LSN

55c58595622947b68e549a4f49ed1944.png

如果重做日志记录到LSN=3906时突然宕机了,并且事务提交了,这时候last checkpoint at=3696,log sequence number=3906,也就是右边的两个页没有实际应用到页里面(也就是事务的结果没最终落地),数据库恢复时,就会吧那两个页应用到对应页中。

Log Sequence number:表示当前的LSN

Log flushed up to:表示刷新到重做日志文件的LSN

Last checkpoint at:表示刷新到磁盘的LSN

数据库恢复时,只需要从Last checkpoint at的位置开始恢复就可以,也就是上面讲的例子 

redo.log的写入特点

从上面的图示中可以看出,redo.log是顺序写的,顺序写的好处就是每次写的时候会用做磁盘寻址,就相当大程度的提高写入效率。这一点很多中间件都会有使用到,比如RocketMQ,Kafka等数据的写入

总结一下

Mysql Innodb数据库引擎的在处理事务提交时是通过两段式提交来完成的。通过结合redo.log,bin.log来完成这个两段式提交的动作。但由于各自文件写入磁盘的时机不同,其在实际存储时的顺序也可能不一样。InnoDB通过三个LSN记录数据库恢复时应该从哪个位置开始,并且恢复时先遍历redo.log,只要是commit状态的直接提交,如果是prepare状态的会检查是否提交bin.log,如果有则提交,如果没有,则不提交

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLOv5、v7、v8的竹签计数系统的设计与实现

文章目录 前言效果演示一、实现思路① 算法原理② 程序流程图 二、系统设计与实现三、模型评估与优化① Yolov5② Yolov7③Yolov8 四、模型对比 前言 该系统是一个综合型的应用,基于PyTorch框架的YOLOv5、YOLOv7和YOLOv8,结合了Django后端和Vue3前端&am…

怎样才能实现私域流量的增长?

为了优化私域流量增长,以下策略可能有效: 1. 价值吸引,而非仅仅是免费: 采用免费策略吸引用户是常见做法,但关键在于通过高价值或服务提升用户体验,确保用户在“获取”免费产品过程中感受到真正的价值。 …

CocoaPods的安装和使用

前言 本篇文章讲述CocoaPods的安装和使用 安装cocoaPods 如果电脑没有安装过cocoaPods,需要先安装,使用下面的命令: sudo gem install cocoapods输入密码后开始安装,需要等待。。。但是我这里报错了。 The last version of d…

17.JVM-[一篇通]

文章目录 JVM1.JVM 简介 (一个进程有一个JVM)1.1JVM 发展史1.2 JVM 和《Java虚拟机规范》 2.JVM 运行流程2.1JVM 执行流程 3.JVM 运行时数据区3.1 堆(线程共享 一个进程只有一份堆)3.2Java虚拟机栈(线程私有 每个线程都有一份属于自己的栈&am…

rancher和k8s接口地址

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux/Windows/Mac 机器上。容器镜像正成为一个新的标准化软件交付方式。为了能够获取到 Docker 容器的运行状态,用户可以…

某瓜数据app 获取达人直播商品信息接口 Sign

文章目录 声明指定直播间获取商品信息达人主页所有的商品列表接口声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请私信我立即删除! 之前写过:某瓜数据app Sign 具体算法分析请看上一篇,这次看一下不同…

大语言模型质量评测(附带全部可运行代码)

代码仓库 大模型训练完之后,怎么知道其回答质量好不好,或者是不是可用的,这就需要我们对大模型进行评测,评测集的制定显得尤为重要。 收集相关数据,我们可以对评测集分为主观题和客观题,这些题目尽可能的包…

I2C接口简介

一、简介 11I2C(Inter-IntegratedCircuit)总线是由PHILIPS公司开发的两线式串行通信总线,使用多主从架构,用于连接微控制器及其外围低速设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形…

程序员裁员潮:技术变革下的职业危机

文章目录 每日一句正能量前言技术变革的影响裁员的影响程序员如何应对裁员潮危机后记 每日一句正能量 书读的越多而不加思考,你就会觉得你知道得很多;而当你读书而思考得越多的时候,你就会越清楚地看到,你知道得很少。 前言 在当…

蓝牙驱动程序错误的疑难问题解决办法(离谱的错误,已经解决)

我的问题介绍: 晚上还是好的,第二天电脑忽然蓝牙驱动坏了,也不知道为什么,然后就是修复 修复过程: 1:自己重新下载网卡驱动 2:自己联系官方客服,下载蓝牙驱动 3:无论…

websocket实现聊天室(vue2 + node)

通过websocket实现简单的聊天室功能 需求分析如图: 搭建的项目结构如图: 前端步骤: vue create socket_demo (创建项目)views下面建立Home , Login组件路由里面配置路径Home组件内部开启websocket连接 前端相关组件代码: Login…

【网络奇遇记】揭秘计算机网络性能指标:全面指南

🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 速率1.1 数据量1.2 速率 二. 带宽三. 吞吐量四. 时延4.1 发送时延4.2 传播时延…

数据结构--数组和广义表

1. 数组的定义 略 2. 数组的顺序表示 由于数组定义后,数组的维度和每维的长度就不再改变,其结构是固定的,因此一般采用顺序存储结构。 3. 特殊矩阵的压缩矩阵 4. 广义表的定义和抽象操作 广义表一些操作可以看数据结构--广义表_空广义表的…

React Router v6 改变页面Title

先说正事再闲聊 1、在路由表加个title字段 2、在index包裹路由 3、在App设置title 闲聊: 看到小黄波浪线了没 就是说默认不支持title字段了 出来的提示, 所以我本来是像下面这样搞的,就是感觉有点难维护,就还是用上面的方法了 …

jquery学习-1

jquery学习-1 1.jquery类似的框架 MooTools 对比反应时间2.Jquery Api jquery api中文文档 jquery注重的是看文档 3.Jquery下载和导入(压缩版) Jquery 下载 下载后导入项目中进行使用 <!DOCTYPE html> <html><head><meta charset"utf-8"…

移动硬盘好还是移动u盘好?区别是什么

随着科技的飞速发展&#xff0c;移动存储设备已经成为人们生活中不可或缺的一部分。其中&#xff0c;移动硬盘和移动U盘是两种常见的存储设备&#xff0c;人们在选择时可能会犯难&#xff0c;不知道选择移动硬盘好还是移动U盘好。 事实上&#xff0c;它们各有千秋。对此&#…

推荐5款提高工作效率和质量的软件

​ 工作学习中&#xff0c;我们常用各种软件&#xff0c;提高效率和质量。有些软件必不可少&#xff0c;有些软件可选择。今天&#xff0c;我给大家介绍5款实用软件。 1.开始菜单——Classic Shell ​ Classic Shell是一款可以恢复Windows系统的传统开始菜单的软件&#xff0…

基于SpringBoot的高校学科竞赛平台管理系统

基于SpringBoot的高校学科竞赛平台管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台界面 管理员界面 教师界面 学生界面 摘要 本文详细介绍了一款基于…

AI对联生成案例(二)

模型训练 有了处理好的数据&#xff0c;我们就可以进行训练了。你可以选择本地训练或在OpenPAI上训练。 OpenPAI上训练 OpenPAI 作为开源平台&#xff0c;提供了完整的 AI 模型训练和资源管理能力&#xff0c;能轻松扩展&#xff0c;并支持各种规模的私有部署、云和混合环境…

【蓝桥杯备赛Java组】语言基础|竞赛常用库函数|输入输出|String的使用|常见的数学方法|大小写转换

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;蓝桥杯&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 一、编程基础 1.1 Java类的创建 1.2 Java方法 1.3 输入输出 1.4 String的使用 二、竞赛常用库函数 1.常见的数学方法 2.大小写转…