一条更新SQL的内部执行

学习MySQL实战45讲,非常推荐学

还是老图:

上文复习

在执行查询语句的时候,会执行连接器(总要连上才能搞事情),然后去查询缓存(MySQL8+删除了),有数据返回,没数据进行分析器-优化器-执行器-执行引擎流程并且其特点是如果该表上有更新,都会把缓存结果清空

MySQL整体来看可以分为两块:一块是Server层,它主要做的是MySQL功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜;

 update T set c=c+1 where ID=2;

流程:

  1. 连接器:连接数据库
  2. 分析器:分析词法和语法解析知道这是更新语句
  3. 优化器:决定使用ID进行索引
  4. 执行器:具体执行,找到改行然后更新

更新对查询来说,涉及到了两个重要的日志模块,redo log(重做日志)InnoDB特有的,binlog(归档日志)Server中存在的,只要持续学习数据库方面,这两个是绕不过的。

redo log(重做日志)

在InnoDB中redo log的大小是固定的,可以配置为一组4个文件,每个文件的大小是1GB,那么这块redo log总共就可以记录4GB的操作(可以自己设置)。

MySQL中的问题:

如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程IO成本、查找成本都很高

解决问题:

WAL技术:Write-Ahead Logging

  1. 写日志
  2. 写磁盘

执行流程:

为什么redo log具有crash-safe的能力

为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?

redo log的被动刷盘机制

明确定义:

write:刷盘

fsync:持久化到磁盘

write(刷盘)指的是MySQL从buffer pool中将内容写到系统的page cache中,并没有持久化到系统磁盘上。这个速度其实是很快的。

fsync指的是从系统的cache中将数据持久化到系统磁盘上。这个速度可以认为比较慢,而且也是IOPS升高的真正原因。

redo log是物理日志,记录的是“在某个数据页上做了什么修改”,内部结构是基于页的,记录了这个页的字段值变化,只要crash后读取redo log进行重放就可以恢复数据。(因为redo log是循环写的,如果满了InnoDB就会执行真正写盘)。

好处是不用每一次操作都实时把数据写盘,就算crash后也可以通过redo log重放恢复,所以能够实现快速响应SQL语句。

binlog(归档日志)

MySQL刚开始是使用的自带引擎MyISAM,但其没有crash-safe,binlog日志只能用于归档,5.5版本之后引入InnoDB,通过redo log来实现crash-safe能力。

redo log与binlog的区别

  1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  2. redo log 是物理日志记录的是在某个数据页上做了什么修改;binlog 是逻辑日志记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志

update内部执行流程:

流程图:图中浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的

其中redo log分为两个阶段提交:这是为了让两份日志之间的逻辑一致

  1. redo log prepare阶段
  2. commit阶段

好处:保证redo log和binlog都能同时失败或者成功。

论证两阶段提交的必要性:

如果不采用两阶段提交,那么redo log和binlog是单独的逻辑,由此引出下面两种提交方式:

  1. 先写redo log,后写binlog
  2. 先写binlog,后写redo log

还是以update为例:

update T set c=c+1 where ID=2;

先写redo log,后写binlog

在redo log写完,binlog没写完的时候,MySQL 进程异常重启,因为其实先写入内存的,所以MySQL崩溃后仍然能把数据恢复

根据备份恢复后c的值为1.但由于binlog没有写完就崩溃了,这时候binlog就没有记录这条语句的操作,使用binlog恢复的时候就会少一次更新,c的值为0,这就与原库的值不同了。

先写binlog,后写redo log与上面逻辑相同都会造成恢复的数据与原库值不同;

可以看到,如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致

但是当按照上述流程图来说,在进行两阶段提交的时候,即A、B时刻出现crash,是怎么处理的。

流程如下:



B时刻发生crash后对应的是2(a)的情况,崩溃恢复过程中事务会被提交。

由此引出的很多问题,感兴趣的朋友可以看下MySQL实战45讲答疑篇第一章

备份的流程:

  1. 找到最近的一次全量备份,从这个备份恢复到临时库;
  2. 从备份的时间点开始,将备份的 binlog 依次取出来,重放到中午误删表之前的那个时刻。

备份恢复的数据的场景:

  1. 误操作后需要恢复数据
  2. 要扩容的时候,也需要再多搭建一些备库来增加系统的读能力的时候,用全量备份加上应用binlog 来实现的。如果这个“不一致”就会导致你的线上出现主从数据库不一致的情况

一条更新SQL的内部执行及日志模块的更多相关文章

  1. JAVA中处理事务的程序--多条更新SQL语句的执行(包括回滚)

    在与数据库操作时,如果执行多条更新的SQL语句(如:update或insert语句),在执行第一条后如果出现异常或电脑断电, 则后面的SQL语句执行不了,这时候设定我们自己提交SQL语句,不让JDBC ...

  2. MySql 学习之 一条更新sql的执行过程

    上一篇文章咱们说了一条查询sql的执行过程.如果没有看过上一篇文章的可以去看下上一篇文章,今天咱们说说一条更新sql的执行过程. 上面一条sql是将id为1的分数加上10. 那么它的执行流程是怎样的呢 ...

  3. MySQL中一条更新语句是如何执行的

    1.创建表的语句和更新的语句 这个表的创建语句,这个表有一个主键ID和一个整型字段c: mysql> create table T(ID int primary key, c int); 如果要 ...

  4. 当程序执行一条查询语句时,MySQL内部到底发生了什么? (说一下 MySQL 执行一条查询语句的内部执行过程?

    先来个最基本的总结阐述,希望各位小伙伴认真的读一下,哈哈: 1)客户端(运行程序)先通过连接器连接到MySql服务器. 2)连接器通过数据库权限身份验证后,会先查询数据库缓存是否存在(之前执行过相同条 ...

  5. MySQL:一条更新语句是如何执行的

    目录 引言 更新流程图 更新流程说明 第一步:更新数据 数据页内存 Change Buffer 第二步:缓存日志内容 redo log buffer binlog cache 第三步:日志写入磁盘 两 ...

  6. 一条查询SQl是怎样执行的

    MySQL的逻辑架构图 大体来说,MySQL可以分为Server层和存储引擎层两部分. Server层包括连接器.查询缓存.分析器,优化器等,涵盖MySQL的大多核心服务功能,以及所有的内置函数,存储 ...

  7. MySQL概述 - 一条查询sql语句的执行过程

    Server层 连接器 建立连接.获取权限.维持和管理连接. 连接建立比较复杂,建议使用长连接 定期断开长连接 mysql_reset_connection指令 查询缓存 建议关闭,任何更新操作会此t ...

  8. MySQL:一条SQL是如何执行的

    目录 MySQL基本架构 Server层 连接器 查询缓存 分析器 优化器 执行器 存储引擎层 InnoDB MyISAM Memory SQL执行流程 MySQL基本架构 在讲SQL语句是如何执行之 ...

  9. MySql 学习之 一条查询sql的执行过程

    相信大家都接触过Mysql数据库,而且也肯定都会写sql.我不知道大家有没有这样的感受,反正我是有过这样的想法.就是当我把一条sql语句写完了,并且执行完得到想要的结果.这时我就在想为什么我写这样的一 ...

随机推荐

  1. 微信小程序版博客——开发汇总总结(附源码)

    花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...

  2. java继承时能包括静态的变量和方法吗?举例说明!

    子类继承了超类定义的所有实例变量和方法包括静态的变量和方法(马克-to-win见下例),并且为它自己增添了独特的元素.子类只能有一个超类.Java不支持多超类的继承. 子类拥有超类的所有成员,但它不能 ...

  3. Mybatis 多表实现多对多查询、添加操作

    Mybatis 多表实现多对多查询.添加操作 学习内容: 1. 多对多之添加操作 1.1.需求 1.2.数据库表(多对多数据库设计需要设计中间表) 1.3.类设计 1.4.Mapper 接口和 Map ...

  4. Python接口自动化——文件上传/下载接口

    〇.前言 文件上传/下载接口与普通接口类似,但是有细微的区别. 如果需要发送文件到服务器,例如:上传文档.图片.视频等,就需要发送二进制数据,上传文件一般使用的都是 Content-Type: mul ...

  5. 自学java如何快速地达到工作的要求?

    自学java如何快速地达到工作的要求,是很多初学者都比较关心的问题,对于初学者来说,盲目自学不但不能快速入门,还会浪费大量的时间. 今天知了堂就来分享自学Java如何快速达到找工作的要求. 1.自学J ...

  6. 图片叠加科幻切换 -- css

    <template> <div>   <div class="a"></div> <div class="b&quo ...

  7. VS Code失焦时自动保存编辑器内容

    vs code有一个非常好用的功能:就是自动保存. 而且不需要安装什么插件,只需要在编辑器设置就可以了.接下来我们一起来设置吧: 1.打开我们的vs code编辑器.在左下角有个  齿轮图标(管理), ...

  8. js逆向之AES加密

    故事背景: 在获取某网站接口数据时,发现其请求的 headers 中的参数 使用了 AES算法加密 ,并对其进行校验,在此简单记录下自己的踩坑历程. AES简介: 高级加密标准(AES,Advance ...

  9. SpringMVC初学习

    # SpringMVC快速入门 @[TOC](文章目录) --- # 前言 `提示:这里可以添加本文要记录的大概内容:` 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习 ...

  10. 【Java分享客栈】从线上环境摘取了四个代码优化记录分享给大家

    前言 因为前段时间新项目已经完成目前趋于稳定,所以最近我被分配到了公司的运维组,负责维护另外一个项目,包含处理客户反馈的日常问题,以及对系统缺陷进行优化. 经过了接近两周的维护,除了日常问题以外,代码 ...