浅析 mysql 两阶段提交

这篇具有很好参考价值的文章主要介绍了浅析 mysql 两阶段提交。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

对流程图主要模块解释

连接器

查询缓存

分析器

优化器

执行器

日志模块

两阶段提交


前言

在业务上,对数据的更新是非常频繁的,mysql 来说就是一条update 语句。大家有没有感觉update 语句对普通索引的更新总是很快,这是为啥呢?是不是很好奇更新语句的执行流程是怎么样的呢?

由于语句执行错误,数据被污染,我们会让DBA 帮我们恢复到更新前的状态,这又是怎么完成的呢?

对于这些问题,会在接下来的文章详细讲解,本章引擎是innodb 引擎。

为了方便讲解,我将画一个流程图,这个流程图包括各层需要的日志文件。

mysql 二阶段提交,mysql,mysql,数据库,mysql 两阶段提交

对流程图主要模块解释

连接器

是主要连接数据库,连接器负责跟客户端建立连接、获取权限、维持和管理连接。客户端具体怎么连接的如下图。

mysql 二阶段提交,mysql,mysql,数据库,mysql 两阶段提交

如上图 3 就是连接命令,如果输密码错误,那么就会返回1的信息,如果密码正确,连接器会到权限表里查出你拥有的权限。之后所以的操作都依赖次权限,不在验证权限,除非重新登录。也就意味着,一个用户成功建立连接后,即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。

一个简单的连接,首先需要tcp 三次握手,其实还需要获取当前连接的权限。这个过程也是挺复杂的,为了提高效率,建议大家用长连接。这样就提高的查询效率,在系统优化时,我们会用连接池去管理这些长连接,在系统启动时都会创建一定数量的连接,以后每次使用的时候,就从连接池拿一个连接,避免了每次因为连接mysql需要tcp 三次握手,获取当前连接权限的资源消耗,提高了系统的响应,这是一个优化点。

长连接是不是越多越好了,当然不是,mysql 在执行过程中临时使用的内存时管理在连接对象里的,这些资源在连接断开时候才释放。 太多的连接会占用太多的内存,内存占用太大,会被操作系统强行OOM掉,mysql 就会异常重启。

长连接如果长时间没有用,mysql 连接器就会自动断开,参数是由 wait_timeout 控制的,默认8小时。如果连接关闭后,在次发动请求,会收到一个错误提醒 Lost connection to MySQL server during query。如果这个时候你要继续就会重连,不过在连接池设计时, 使用连接前会先去ping,如果没有返回错误,关掉这个连接,重新建一个连接,为了避免一个连接占用太多的内存,在连接池设计中,连接都是有生命周期的,到了时间就释放掉。在mysql 客户端,如果执行了一个特别大的操作,通常会执行 mysql_reset_connection 重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

查询缓存

查询缓存,在以前版本还有,我的mysql8.0 版本已经去掉了,它的存储是key,value 形式。以前查询的记录会放到缓存,再次查询从查询缓存返回。如果表更新,这个表的所有缓存都清空。弊大于利。

分析器

分析器包括词法分析和语法分析,先进行词法分析,sql 语句都是由字符串和空格组成。分析出sql 语句的关键字,select ,update。mysql 在server 层需要知道你做什么,告诉存储引擎需要给我什么东西或进行什么操作,还要分析出表名,对哪个表操作。还有字段名,对某些字段进行操作。然后需要进行语法分析,分析出sql 是否有语法错误,有语法错误,就会返回 You have an error in your SQL syntax。

优化器

优化器决定sql 用哪个索引,会根据引擎要扫描的行数,回表等因素计算成本,会选择一个成本最低的,效率高的索引。对于join 表,会根据表的行数决定表的连接数序,哪个表是左表。

执行器

执行器已经拿到表名了,还要看这个连接对表有没有执行权限,如果有,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。

日志模块

日志模块主要是讲redo log 和 binlog

redo log 是innodb 引擎特有的,是在引擎层。为mysql 提供了crash-safe的能力,可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,它记录的是某页做了什么修改。大小是固定的,这个可以根据磁盘去设置。由于大小是固定的,所以是循环写,会把以前的记录覆盖掉。

binlog 是在server 层,所有的存储引擎都可以用,也叫归档日志。它有几种模式,statement 记录sql 语句, row 记录每一行数据修改形式,mixed 是混合模式。主要用在数据恢复,主从,还有比如CDC 去消费binlog 去完成相关业务。

这两个日志缺一不可,缺少了 redo log 。mysql 崩溃有可能造成数据丢失,缺少binlog 数据就没法备份。

两阶段提交

我们在分布式事务也有一种两阶段提交,都是为了保证数据的一种,mysql 的两阶段提交,是为了保证数据库与数据备份的数据一致性,说白了就是保证binlog 与 redo log 数据的一致性。

我们拿更新过程来说吧,比如一个语句是 update t set a=1 where 1=1. 如上图2 所示

  1. 首先会判断buffer pool 是否有这条记录,如果没有,就根据索引,从页里读出来,放到buffer pool 里,会记录它属于某个页的具体信息

  2. 会在redo log 里记录某页进行了什么修改,此时的redo log 是 prepare 状态,同时也会在 buffer pool 的 chang buffer 进行相应的记录

  3. 存储引擎层会通知 server 层,在binlog 记录这条语句的修改

  4. binlog 记录完成了,通知redo log 把prepare 改成commit 状态。

上面就是两阶段提交的基本步骤。

大家有时在想 binlog 写完,redo log 还没 commit 前发生 crash,那崩溃恢复的时候 MySQL 会怎么处理?毕竟这个过程确实存在。

  1. 如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;

  2. 如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:如果是就提交事务,否则就会滚

那么分析到现在就是怎么判断 binlog 是否存在并完整呢?

  1. statement 格式的 binlog,最后会有 COMMIT;

  2. row 格式的 binlog,最后会有一个 XID event。

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

那么怎么恢复呢?

这两个日志有一个共同的数据字段 叫 XID。mysql 崩溃恢复的时候会去扫码 redo log. 如果 redo log 有commit ,就直接提交,恢复 change buffer 相关的内容。如果没有commit 就去bin log 找是否有对应的 XID,有的话,binlog 也直接提交,没有的话,就回滚。文章来源地址https://www.toymoban.com/news/detail-848422.html

到了这里,关于浅析 mysql 两阶段提交的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据库原理】(29)数据库设计-需求分析阶段

    需求分析就是调查、收集、分析、最后定义用户对数据库的各种要求。它是整个数据库设计的基础和出发点,其结果将直接影响后面各步的设计,甚至决定着最终设计的数据库的好坏与成败。为此,首先必须知道需求分析的任务是什么,以及采用什么样的方法进行需求分析。 这阶

    2024年01月17日
    浏览(58)
  • 【手写数据库toadb】01 开发数据库内核准备阶段-开发环境准备

    ​ 专栏内容 : 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学

    2024年01月22日
    浏览(48)
  • 【手写数据库toadb】02 开发数据库内核准备阶段-git工具使用

    ​ 专栏内容 : 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学

    2024年01月24日
    浏览(48)
  • 分布式数据库 Join 查询设计与实现浅析

    相对于单例数据库的查询操作,分布式数据查询会有很多技术难题。 本文记录 Mysql 分库分表 和 Elasticsearch Join 查询的实现思路,了解分布式场景数据处理的设计方案。 文章从常用的关系型数据库 MySQL 的分库分表Join 分析,再到非关系型 ElasticSearch 来分析 Join 实现策略。逐步

    2024年02月08日
    浏览(39)
  • 阶段七第二章连接数据库,逻辑控制器,定时器,分布式

    准备工作 : 1.启动数据库 2.加载mysql的JDBC驱动 · 方法1:在测试计划下方的位置,点击浏览添加JDBC的jar包 · 方法2:将JDBC的jar拷贝到lib目录,并重启jmeter 3.JDBC连接池配置参数: 编写JDBC脚本步骤 :(搜索指定商品,在返回结果中检查是否包含指定商品的ID的URL) 1、添加JDBC

    2024年01月22日
    浏览(56)
  • [架构之路-236]:目标系统 - 纵向分层 - 数据库 - 数据库系统基础与概述:三阶段模型(概念模型、逻辑模型、物理模型)、三级模式结构(外模式、模式、内模式)

    目录 一、数据库设计阶段性模型:概念模型、逻辑模型、物理模型 1.1 概念模型(Conceptual Model)- 业务模型: 实体:entity 属性或特征: key键值/码: 域(Domain): 实体类型:entity type 实体集合: 联系: 1.2 逻辑模型(Logical Model)- 内存模型(最核心): 1.3 物理模型(Phys

    2024年02月02日
    浏览(63)
  • 海山数据库(He3DB)原理剖析:浅析Doris跨源分析能力

    Doris多数据源功能演进 Doris的生态近年来围绕湖仓分析做了较多工作,Doris一直在积极拓宽大数据生态的OLAP分析市场,Doris2.0之后为了满足湖仓分析场景,围绕multi-catalog、数据缓存、容错、pipeline资源管理等做了不少改进。 首先在multi-catalog之前,Doris访问Hive表需要单表映射或

    2024年04月12日
    浏览(32)
  • 2022 十二月 GBase8a 班阶段考试 01 - 数据库运维知识 答案

    2022 十二月 GBase8a 班阶段考试 01 - 数据库运维知识 多选题(4.5 分) 以下关于粗粒度智能索引描述正确的是( )? A.记录 DC 内的最大值、最小值、空值、求和值等。 B.免维护,自动建立。 C.索引的建立和维护对资源的消耗可以忽略不计。 D.每一列数据都会生成一个粗粒度智能

    2024年02月09日
    浏览(45)
  • 编写一个微信小程序,实现表单提交数据到云数据库

    好的。 首先,你需要在微信公众平台中创建一个小程序,并在小程序的后台获取到云开发的相关权限。然后你就可以使用微信小程序开发工具进行开发了。 在页面中创建一个表单,并在表单中添加输入框和提交按钮。 在小程序的 app.js 文件中初始化云开发环境。 在表单的提

    2024年02月07日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包