Innodb存储引擎-执行流程分析和二阶段提交分析

news2024/11/14 17:41:12

文章目录

      • 执行流程分析
        • 基本流程
        • WAL(Write-Ahead Log)
        • write和fsync区别
        • innodb_flush_logs_at_trx_commit & sync_binlog
        • 二阶段提交

执行流程分析

基本流程

(1)连接,分析,优化,执行

客户端与MySQL Server建立连接,发送语句给MySQL Server,接收到后如果是查询语句会先去查询缓存中看,有的话就直接返回了,(新版本的MySQL已经废除了查询缓存,命中率太低了),如果是缓存没有或者是非查询语句,会进行语法分析并创建一个解析树,然后进行优化,(解析器知道语句是要执行什么,会评估使用各种索引的代价,然后去使用索引,以及调节表的连接顺序)然后调用innodb引擎的接口来执行语句。

(2)写undo log

innodb 引擎首先开启事务,获得一个事务ID(是一直递增的),根据执行的语句生成一个反向的语句,(如果是INSERT会生成一条DELETE语句,如果UPDATE语句就会生成一个UPDATE成旧数据的语句),用于提交失败后回滚,将这条反向语句写入undo log,得到回滚指针,并且更新这个数据行的回滚指针和事务id。(事务提交后,Undo log并不能立马被删除,而是放入待清理的链表,由purge 线程判断是否有其他事务在使用undo 段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间,简单的说就是看之前的事务是否提交成功,这个事务及之前的事务都提交成功了,这部分undo log才能删除)

(3)从索引中查找数据

根据索引去B+树中找到这一行数据(如果是普通索引,查到不符合条件的索引,会把所有数据查找出来,唯一性索引查到第一个数据就可以了)

(4)更新数据

判断数据页是否在内存中?

  1. 数据页在内存中。若为普通索引,直接更新内存中的数据页;若为唯一性索引,判断更新后是否会数据冲突(不能破坏索引的唯一性),不会的话就更新内存中的数据页。
  2. 数据页不在内存中。若为普通索引,将对数据页的更新操作记录到change buffer,在下一次查询时需要访问这个数据页时,再执行change buffer中的操作对数据页进行更新。(或者是在MySQL Server空闲时,会将change buffer中所有操作更新到磁盘,也就是俗称的‘刷页’。);若为唯一性索引,因为需要保证更新后的唯一性,所以不能延迟更新,必须把数据页从磁盘加载到内存,然后判断更新后是否会数据冲突,不会的话就更新数据页。

(5)写redo log(prepare状态)

将对数据页的更改写入到redo log,此时redo log中这条事务的状态为prepare状态。

(6)写bin log(同时将redo log设置为commit状态)

更新时,先改内存中的数据页,将更新操作写入redo log日志,此时redo log进入prepare状态,然后通知MySQL Server执行完了,随时可以提交,MySQL Server将更新的SQL写入bin log,然后调用innodb引擎接口将redo log设置为提交状态,更新完成。

WAL(Write-Ahead Log)

Write-ahead Log的思路:先在内存中提交事务,然后写日志(所谓的Write-ahead Log),然后后台任务把内存中的数据异步刷到磁盘。日志是顺序地在尾部Append,从而也就避免了一个事务发生多次磁盘随机 I/O 的问题。明明是先在内存中提交事务,后写的日志,为什么叫作Write-Ahead呢?这里的Ahead,其实是指相对于真正的数据刷到磁盘,因为是先写的日志,后把内存数据刷到磁盘,所以叫Write- Ahead Log。

具体到InnoDB中,Write-Ahead Log是Redo Log。在InnoDB中,不 光事务修改的数据库表数据是异步刷盘的,连Redo Log的写入本身也是异步的。

write和fsync区别

这里我们首先要明确两个概念和两个参数:

  • write:刷盘。指的是MySQL从buffer pool中将内容写到系统的page cache中,并没有持久化到系统磁盘上。这个速度其实是很快的。
  • fsync:同步持久化到磁盘。指的是从系统的cache中将数据持久化到系统磁盘上。这个速度可以认为比较慢,而且也是IOPS升高的真正原因。

innodb_flush_logs_at_trx_commit & sync_binlog

innodb_flush_logs_at_trx_commit(redo log):

  • 0 :设置为 0 的时候,表示每次事务提交时不进行刷盘操作,每次提交事务都只把redo log留在redo log buffer中
  • 1(默认值) :设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值),每次提交事务都将redo log 持久化到磁盘上,也就是write+fsync
  • 2 :设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache ,也就是只write,不fsync

sync_binlog(binlog)

  • 0(默认值):当事务提交之后,将binlog 从binlog cache中 write到磁盘上,不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让File system自行决定什么时候来做同步,或者cache满了之后才同步到磁盘,性能最佳
  • 1:当每进行1次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘,是最慢的,但是最安全
  • N:每次提交事务都将binlog write到磁盘上,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。

参考:MySQL日志(redo log、binlog)刷盘策略 - Philosophy - 博客园 (cnblogs.com)

二阶段提交

正常情况下两阶段提交配合组提交的流程如下:

在双一模式下的流程,每个事务提交时都需要进行fsync刷盘,其执行过程才如上图所示。然而在配合两个参数sync_binlog和innodb_flush_log_at_trx_commit,上图会有所调整。

innodb_flush_log_at_trx_commit在非1的情况下,步骤三可以忽略:

  • innodb_flush_log_at_trx_commit=0,redo log日志条目写入到redo log buffer中,MySQL即认为redo log已完成写入,即redo log prepare状态,可以进行下一步动作。
  • innodb_flush_log_at_trx_commit=2,redo log日志条目写入到文件系统缓存page cache,MySQL即认为已完成redo log完成写入,即redo log prepare状态,可以进行下一步动作。此时的刷盘由MySQL的后台主线程和操作系统层进行完成。

sync_binlog在非1的情况下,步骤四可以进行忽略:

  • sync_binlog=0,binlog只需要写入到binlog cache即可进行下一步,此刻MySQL会认为binlog已完成写入,redo log和binlog达成一致,redo log可以commit。
  • sync_binlog=N(N>1),每个事务的binlog都写入到binlog cache,攒够N个事务之后,集中fsync刷盘(由后台主线程处理),此刻MySQL会认为binlog已完成写入,redo log和binlog达成一致,redo log可以commit。

那么两段提交过程中失败会发生什么结果呢?MySQL又是怎样处理的呢?

首先我们先放一下两段提交的图:

接下来,我们就一起分析一下在两阶段提交的不同时刻,MySQL 异常重启会出现什么现象。

如果在图中时刻 A 的地方,也就是写入 redo log 处于 prepare 阶段之后、写 binlog 之前,发生了崩溃(crash),由于此时 binlog 还没写,redo log 也还没提交,所以崩溃恢复的时候,这个事务会回滚。这时候,binlog 还没写,所以也不会传到备库。

如果在图中在时刻 B,也就是 binlog 写完,redo log 还没 commit 前发生 crash,那崩溃恢复的时候 MySQL 会怎么处理?

我们先来看一下崩溃恢复时的判断规则:

  • 如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;
  • 如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:
    • 如果是,则提交事务;
    • 否则,回滚事务。

这里,时刻 B 发生 crash ,崩溃恢复过程中事务会被提交。

那么问题又来了,MySQL是如何判断binlog是不是完整的呢?

我们都知道binlog有三种格式statement、row、mix。其中mix是前两种方式的组合,一个事务的binlog是有完整的格式的,

  • statement 格式的 binlog,最后会有 COMMIT;
  • row 格式的 binlog,最后会有一个 XID event。

另外,在 MySQL 5.6 版本以后,还引入了 binlog-checksum 参数,用来验证 binlog 内容的正确性。对于 binlog 日志由于磁盘原因,可能会在日志中间出错的情况,MySQL 可以通过校验 checksum 的结果来发现。所以,MySQL 还是有办法验证事务 binlog 的完整性的。

而且redolog和binlog有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log:如果碰到既有 prepare、又有 commit 的 redo log,就直接提交; 如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。这样在两段提交的前提下就能完全保证事务的特性了。

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

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

相关文章

2022.12.18 学习周报

文章目录摘要文献阅读1.题目2.摘要3.介绍4.RNNConventional Recurrent Neural Networks5.Deep Recurrent Neural Networks5.1 Deep Transition RNN5.2 Deep Output5.3 Stacked RNN6.实验6.1 训练6.2 结果与分析7.讨论深度学习GRU公式推导1.GRU前向传播2.GRU反向传播GRU代码实现…

关于数学中“函数(function)”的含义

目录 1. 问题 2. “function”是如何翻译成“函数”的? 3. “function”是谁引入数学中的,其意义何在? 3.1 “function”的词源 3.2 “function”引入数学中 3.3 “function”的含义 4. 常见的函数(Common Functions) 4.1 线性函数(L…

word页码如何设置为章节加页码,例如第一章第一页1-1、第二章章第一页2-1

由于用到word页码分章节页码的形式,从网上查了一下,质量真的很差,没有一篇文章讲清楚的,有的所答非所问,一怒之下,利用几个小时的时间解决问题并写下这篇文章,以供大家学习参考!&…

【JSP】

文章目录简介Scriptlet脚本小程序JSP的指令标签include静态包含include动态包含不传参传参JSP的四大域对象四种属性范围验证属性范围的特点EL表达式操作字符串操作集合emptyJSTL条件动作标签if标签choose、when 和 otherwise 标签迭代标签foreach格式化动作标签formatNumber标签…

NProgress 进度条的使用方法

安装NProgress 进度条 npm install nprogress --save-dev 在vue项目中mian.js中或router.js或axios.js: import NProgress from nprogress import nprogress/nprogress.css 使用NProgress进度条 NProgress.start(); :进度条开始; NProgr…

GCD和LCM

目录 一 整除 定义 性质 二 GCD 1)定义 2)性质 3)GCD编程 ①暴力法 ②欧几里得算法 ③更相减损术 ④Stein算法 三 LCM ①暴力法 ②最大公约数法 四 裴蜀定理 例题:裴蜀定理 一 整除 定义 a 能整除b,记为 a|b。其…

你还会想起这道题吗

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 原神是由米哈游自主研发的一款全新开放世界冒险游戏。游戏发生在一个被称作「提瓦特」的幻想世界,在这里,被神选中的人将被授予「神之眼」,导引元…

m基于神经网络的气候预测matlab仿真,气候数据采用的BoM气候数据,神经网络为matlab编程实现不使用工具箱函数

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model&#xff09…

UICollectionView 实际使用

一. 使用UICollectionView制作书架 我想的书架是那种每一排都可以滑动的。暂时的想法是使用两个collectionView,第一个collectionView布置书架的每一排,第二个布置每一排内部的书。 布置外部的colletionView,这部分很简单,item的…

[ 数据结构 -- 手撕排序算法第五篇 ] 堆排序

文章目录前言一、常见的排序算法二、堆的概念及结构三、堆的实现3.1 堆的插入3.2 堆的删除四、堆排序4.1 向上调整建堆4.2 向下调整建堆4.3 建堆的时间复杂度4.4 堆排序五、堆排序的特性前言 手撕排序算法第五篇:堆排序! 从本篇文章开始,我会…

Java+JSP超市管理系统(含源码+论文+答辩PPT等)

项目功能简介: 该项目采用的技术后台框架:Servlet、JSP、JDBC、UI界面:BootStrap、jQuery、数据库:MySQL 系统功能 该系统共包含两种角色:员工和管理员。系统的主要功能模块如下: 1.系统管理 系统登陆、系统退出、修改…

《Mysql是怎样运行的》补充

19 第19章 从猫爷被杀说起-事务简介 19.1 事务的起源 19.1.1 原子性(Atomicity) 19.1.2 隔离性(Isolation) 其它的状态转换不会影响到本次状态转换,这个规则被称之为 隔离性 19.1.3 一致性(Consisten…

[ISITDTU 2019]EasyPHP rce替换字母

<?php highlight_file(__FILE__);$_ $_GET[_]; if ( preg_match(/[\x00- 0-9\"$&.,|[{_defgops\x7F]/i, $_) )die(ros will not do it);if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )die(you are so close, omg);eval($_); ?> 打开界面有两个i…

Mysql分布式锁(四)乐观锁实现并发

文章目录CAS - Compare And Swap业务改造1. 表结构新增version列2. 修改代码3. 测试问题1. 高并发情况下&#xff0c;性能极低2. ABA问题3. 读写分离情况下导致乐观锁不可靠CAS - Compare And Swap 先比较再交换&#xff0c;一般通过时间戳或者version版本号。 举例&#xff1…

【审计思路】如何快速定位SQLMS注入漏洞?

0x00 前言 MCMS是政府、教育等其他行业常用的CMS&#xff0c;应用广泛&#xff0c;但是底层的代码中仍然遗留不少的问题。这篇文章主要针对SQL注入进行审计并探讨如何快速定位SQL注入漏洞&#xff0c;以及其他工具的应用。 MCMS&#xff0c;是完整开源的Java CMS&#xff01;基…

[ vulhub漏洞复现篇 ] Apache Airflow Celery 消息中间件命令执行漏洞复现 CVE-2020-11981

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

基于asp.net企业网上办公自动化系统-计算机毕业设计

企业网上办公自动化通过对各办公自动化要素的闭环整合&#xff0c;实现了工作流、信息流、知识流和办公自动化系统的整合管理&#xff0c;提供了一个科学、开放、先进的信息化办公平台&#xff0c;实现办公自动化&#xff0c;并进行远程办公或在家办公。企业网上办公自动化将人…

redis开启二级缓存

目录 1. redis集成 2. pom.xml加入redis缓存支持 3. 在项目配置文件中加入cache配置 4. 在启动类开发缓存功能 5. 需要缓存的实体对象实现序列化接口 6. 缓存的使用 7. 测试 今天与大家分享&#xff0c;redis二级缓存实现案例。如有问题&#xff0c;望指教。 1. redis集…

计算机毕业设计springboot+vue基本微信小程序的校园二手物品交易平台系统

项目介绍 目的:设计一个同学们能自由发布和浏览求购或卖出商品信息的校园二手交易小程序,解决信息的不流通以及传统二手商品信息交流方式的笨拙等问题。 意义:在大学校园里,存在着很多的二手商品,但是由于信息资源的不流通以及传统二手商品信息交流方式的笨拙,导致了很多仍然具…

十年阿里测试工程师浅谈UnitTest单元测试框架

一、UnitTest单元测试框架提供了那些功能 1.提供用例组织和执行 如何定义一条“测试用例”? 如何灵活地控制这些“测试用例”的执行? 2.提供丰定的断言方法 当测试用例的执行结果与预期结果不一致时&#xff0c;判定测试用例失败。在自动化测试中&#xff0c;通过“断言”…