| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 通过一条更新语句的执行,深入理解 InnoDB 的底层架构 -> 正文阅读 |
|
[大数据]通过一条更新语句的执行,深入理解 InnoDB 的底层架构 |
通过一条更新语句的执行,深入理解 InnoDB 的底层架构前面通过 一条查询SQL的执行过程 我们知道了 MySQL 的整体架构。对一条查询 SQL 语句的执行流程,也有了整体的了解。 查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。 那么,一条更新语句的执行流程又是怎样的呢? MySQL 最常用的存储引擎是 InnoDB,我们今天就通过一条更新语句,分析 InnoDB 具体是如何处理的,深入理解下它的架构。 InnoDB从 InnoDB 的特点是支持事务、支持行锁、支持MVCC、外键,提供一致性非锁定读,同时本身设计能够最有效的利用内存和 CPU。 InnoDB 重要的内存结构InnoDB存储引擎在内存中有两个非常重要的组件,分别是缓冲池(buffer pool)和重做日志缓存(redo log buffer)。 Buffer Pool缓冲池其实就是一块内存区域,作用就是弥补磁盘速度较慢对数据库性能产生的影响。 MySQL 表数据是以页为单位,当查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,然后放入到 InnoDB 每次查询时,首先判断该页是否在缓冲池中。如果在就直接读取,否则,读取磁盘。减少硬盘 IO 开销,提升性能。 更新表数据的时候,如果
Redo Log假设我们把 为了保证数据的持久性,InnoDB 存储引擎加入了 我们都知道 InnoDB 是支持事务机制的,事务有四个特性:原子性、一致性、隔离性、持久性。 InnoDB 事务日志有两部分组成:
Redo Log 的基本概念
MySQL 每执行一条 DML 语句,先将记录写入 这种先写先写 Redo LogInnoDB 的
Undo Log
当执行 了解了这些我们再来看更新语句的执行流程。 更新语句的执行流程建表语句:这个表有一个主键 ID 和一个整型字段 c :
如果要将
首先可以确定的说,查询语句的那一套流程,更新语句也是同样会走一遍。 但是和查询流程不一样的是,更新流程还涉及 更新语句的执行流程如下:
一个更新语句的大致流程介绍完了,下面我们介绍下 Change Buffer
当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InnoDB 会将这些更新操作缓存在 在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 通过这种方式就能保证这个数据逻辑的正确性。 我们知道了 这个问题涉及到索引相关,我们先给出结论,后面在分析索引的时候在详细介绍。 只有满足了更新的记录的索引是普通索引,并且更新记录的数据页不在内存中,这两个条件,才会将更新操作记录到 Binlog前面我们讲过,MySQL 整体来看,其实就有两块:
上面我们聊到的
在实际应用中, Binlog 日志格式
MySQL 为什么会有两份日志最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog 日志只能用于归档。 而 InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统——也就是 redo log 来实现 crash-safe 能力。 binlog 和 redo log 的区别这两种日志有以下三点不同。
有了对这些日志的概念性理解,我们再来看执行器和 InnoDB 引擎在执行这个简单的 update 语句时的内部流程。 执行器和 InnoDB 引擎执行 update 语句时的内部流程
下面是这个 update 语句的执行流程图。图中绿色框表示是在 InnoDB 内部执行的,蓝色框表示是在执行器中执行的。
两阶段提交为什么必须有「两阶段提交」呢?这里我们用反证法来进行解释。 由于 我们看看这两种方式会有什么问题。 假设当前 ID=2 的行,字段 c 的值是 0,再假设执行 update 语句过程中在写完第一个日志后,第二个日志还没有写完期间发生了 crash,会出现什么情况呢? 1、先写 redo log 后写 binlog。 假设在 由于我们前面说过的, 但是由于 因此,之后备份日志的时候,存起来的 然后你会发现,如果需要用这个 2、先写 binlog 后写 redo log。 如果在 但是 所以,在之后用 可以看到,如果不使用「两阶段提交」,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。 你可能会说,这个概率是不是很低,平时也没有什么动不动就需要恢复临时库的场景呀? 其实不是的,不只是误操作后需要用这个过程来恢复数据。当数据库需要扩容的时候,也就是需要再多搭建一些备库来增加系统的读能力的时候,现在常见的做法也是用全量备份加上应用 简单说, 总结本文介绍了 InnoDB 重要的内存结构,包括:缓冲池(buffer pool)和重做日志缓存(redo log buffer)。 还介绍了InnoDB 事务日志: 我们还分析了更新语句的执行流程以及和查询语句的区别。 最后我们介绍了 Binlog 和两阶段提交。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 11:44:53- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |