0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简述SQL更新语句的执行流程2

jf_78858299 来源:蝉沐风的码场 作者:蝉沐风的码场 2023-02-14 15:40 次阅读

4. undo日志

undo log(撤销日志或回滚日志)记录了事务发生之前的数据状态,分为insert undo log和update undo log。

如果修改数据时出现异常,可以用 undo log来实现回滚操作(保持原子性)。可以理解为undo日志记录的是反向的操作,比如INSERT操作会记录DELETE,UPDATE会记录UPDATE之前的值,和redo日志记录在哪个物理页面做了什么操作不同,所以这是一种逻辑格式的日志。

undo日志和redo日志与事务密切相关,被统称为「事务日志」。

图片

关于undo日志,我们目前只需要了解这么多即可

5. SQL更新语句的执行总结——初版

有了事务日志之后,我们来简单总结一下更新操作的流程,这是一个简化的过程。

name 原值是chanmufeng

update t_user_innodb set name ='chanmufeng1994' where id = 1;
  1. 事务开始,从内存(Buffer Pool)或磁盘取到包含这条数据的数据页,返回给 Server 的执行器;
  2. Server 的执行器修改数据页的这一行数据的值为 chanmufeng1994;
  3. 记录 name=chanmufeng 到undo log;
  4. 记录 name=chanmufeng1994到redo log;
  5. 调用存储引擎接口,记录数据页到Buffer Pool(修改 name=penyuyan);
  6. 事务提交。

6. binlog日志

之前我们讲过,从MySQL整体架构来看,其实可以分成两部分

  • Server 层,它主要做的是 MySQL功能层面的事情,比如处理连接、解析优化等;
  • 存储引擎层,负责存储相关的具体事宜。

redo日志是InnoDB存储引擎特有的日志,而Server层也有自己的日志,称为 binlog(归档日志),它可以被所有存储引擎使用。

6.1 为什么有了redo日志还需要 binlog?

我想你可能会问出这个问题,实际上,更准确的问法是为什么有了binlog还需要有redo日志?主要有以下几个原因。

  1. 因为最开始MySQL里并没有InnoDB存储引擎。MySQL自带的引擎是MyISAM,但是 MyISAM没有崩溃恢复的能力,InnoDB后来以插件的形式被引入,顺便带来了redo日志;
  2. binlog日志是用来归档的,binlog以事件的形式记录了所有的 DDL和 DML 语句(因为它记录的是操作而不是 数据值,属于逻辑日志),但是不具备宕机恢复的功能,因为可能没有来得及刷新脏页,造成脏页数据的丢失,而这些操作也没有保存到binlog中从而造成数据丢失;
  3. binlog记录的是关于一个事务的具体操作内容,即该日志是逻辑日志。而redo日志记录的是关于每个页的更改的物理情况。功能压根不是一回事儿。

6.2 binlog日志的作用

6.2.1 主从复制

binlog是实现MySQL主从复制功能的核心组件。

master节点会将所有的写操作记录到binlog中,slave节点会有专门的I/O线程读取master节点的binlog,将写操作同步到当前所在的slave节点。

图片

6.2.2 数据恢复

假如你在阅读这篇文章的时候觉得我写得实在太好,拍案叫绝的时候一不小心把公司的数据库给删了,你该怎么做才能恢复到你删库之前的那个时刻的状态?

这个时候就要用到binlog了,前提是binlog没有被删除,否则,神仙也救不了你了。

通常情况下,公司会定期对数据库进行全量备份,可能隔一个月,一周,甚至可能每天都备份一次。运气好的话你可以使用前一天的全量备份,恢复到前一天的某时刻状态(或者一周、一月之前),然后从全量备份的时刻开始,从binlog中提取该时刻之后(前提是你的binlog里面存放了这段时间的日志)的所有写操作(当然,你得过滤掉你的删库操作),然后进行操作回放就可以了。

是不是很简单?

问题又来了。再看一眼我们的更新语句。

update t_user_innodb set name ='chanmufeng1994' where id = 1;

假如这条更新语句已经被写入到了redo日志,还没来得及写binlog的时候,MySQL宕机重启了,我们看一下会发生什么。

因为redo日志可以在重启的时候用于恢复数据,所以写入磁盘的是chanmufeng1994。但是binlog里面没有记录这个逻辑日志,所以这时候用binlog去恢复数据或者同步到从库,就会出现数据不一致的情况。

所以在写两个日志的情况下,就类似于「分布式事务」的情况,如果你不清楚分布式事务是个什么东西也没关系,我在之后的文章会介绍到。能够明确的就是redo日志和binlog日志如果单纯依次进行提交是无法保证两种日志都写成功或者都写失败的。

我们需要「两阶段提交」。

6.3 两阶段提交

两阶段提交不是MySQL的专利,两阶段提交是一种跨系统维持数据逻辑一致性的常见方案,尤其在分布式事务上,所以请读者重点体会思想

我们把redo日志的提交分成两步,两步中redo日志的状态分别是preparecommit。步骤如下

  1. InnoDB存储引擎将更改更新到内存中后,同时将这个更新操作记录到redo日志里面,此时redo日志处于prepare状态;
  2. 执行器生成这个操作的binlog,并将binlog刷盘;
  3. 执行器调用InnoDB的提交事务接口,InnoDB把刚刚写入的redo日志改成commit状态。至此,所有操作完成。

图片

加上两阶段提交之后我们再来看一下SQL更新语句的执行流程。

7. SQL更新语句的执行总结——终版

图片

  1. 客户端发送更新命令到MySQL服务器,经过处理连接、解析优化等步骤;
  2. Server层向InnoDB存储引擎要id=1的这条记录;
  3. 存储引擎先从缓存中查找这条记录,有的话直接返回,没有则从磁盘加载到缓存中然后返回;
  4. Server层执行器修改这条记录的name字段值;
  5. 存储引擎更新修改到内存中;
  6. 存储引擎记录redo日志,并将状态设置为prepare状态;
  7. 存储引擎通知执行器,修改完毕,可以进行事务提交;
  8. Server先写了个binlog;
  9. Server提交事务;
  10. 存储引擎将redo日志中和当前事务相关的记录状态设置为commit状态。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
收藏 人收藏

    评论

    相关推荐

    为什么要动态sql语句

    为什么要动态sql语句?因为动态sql语句能够提供一些比较友好的机制1、可以使得一些在编译过程中无法获得完整的sql
    发表于 12-20 06:00

    数据库SQL语句电子教程

    电子发烧友为您提供了数据库SQL语句电子教程,帮助您了解数据库 SQL语句 ,学习读懂数据库SQL语句
    发表于 07-14 17:09 0次下载

    sql语句实例讲解

    SQL是用来存取关系数据库的语言,具有查询、操纵、定义和控制关系型数据库的四方面功能。常见的关系数据库有Oracle,SQLServer,DB2,Sybase。开源不收费的有MYSQL,SQLLite等。今天我们主要以MYSQL为例子,讲解
    发表于 11-17 12:39 9155次阅读
    <b class='flag-5'>sql</b><b class='flag-5'>语句</b>实例讲解

    MySQL存储引擎完成更新语句执行的方法

    首先肯定是我们的系统通过一个数据库连接发送到了MySQL上,然后肯定会经过SQL接口、解析器、优化器、执行器几个环节,解析SQL语句,生成执行
    的头像 发表于 10-21 10:40 2060次阅读
    MySQL存储引擎完成<b class='flag-5'>更新语句</b><b class='flag-5'>执行</b>的方法

    select语句和update语句分别是怎么执行

    最近有粉丝面试互联网公司被问到:你知道select语句和update语句分别是怎么执行的吗?,要我写一篇这两者执行SQL
    的头像 发表于 11-03 09:41 3579次阅读
    select<b class='flag-5'>语句</b>和update<b class='flag-5'>语句</b>分别是怎么<b class='flag-5'>执行</b>的

    SQL后悔药,SQL性能优化和SQL规范优雅

    =10086orage=18; 2、操作delete或者update语句,加个limit(SQL后悔药) 在执行删除或者更新语句,尽量加上l
    的头像 发表于 11-14 09:54 1842次阅读

    一条SQL语句是怎么被执行

    一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了。 本文将从MySQL总体架构---》查询
    的头像 发表于 09-12 09:44 1522次阅读
    一条<b class='flag-5'>SQL</b><b class='flag-5'>语句</b>是怎么被<b class='flag-5'>执行</b>的

    简述SQL更新语句执行流程1

    之前我们讲过了一条SQL查询语句是如何执行的,那么插入(INSERT)、更新(UPDATE)和删除(DELETE)操作的流程又是什么样子呢?
    的头像 发表于 02-14 15:40 621次阅读
    <b class='flag-5'>简述</b><b class='flag-5'>SQL</b><b class='flag-5'>更新语句</b>的<b class='flag-5'>执行</b><b class='flag-5'>流程</b>1

    一条SQL更新语句执行流程1

    什么是InnoDB页?缓存页又是什么?为什么这么设计? * 什么是表空间?不同存储引擎的表在文件系统的底层表示上有什么区别? * Buffer Pool是什么?为什么需要?有哪些我们需要掌握的细节? * MySQL
    的头像 发表于 03-03 10:02 634次阅读
    一条<b class='flag-5'>SQL</b><b class='flag-5'>更新语句</b>的<b class='flag-5'>执行</b><b class='flag-5'>流程</b>1

    一条SQL更新语句执行流程2

    什么是InnoDB页?缓存页又是什么?为什么这么设计? * 什么是表空间?不同存储引擎的表在文件系统的底层表示上有什么区别? * Buffer Pool是什么?为什么需要?有哪些我们需要掌握的细节? * MySQL
    的头像 发表于 03-03 10:02 491次阅读
    一条<b class='flag-5'>SQL</b><b class='flag-5'>更新语句</b>的<b class='flag-5'>执行</b><b class='flag-5'>流程</b><b class='flag-5'>2</b>

    oracle更新clob字段sql语句

    在Oracle中,更新CLOB字段可以使用UPDATE语句。CLOB字段是用于存储大量文本数据的数据类型,可以存储最多4GB的数据。下面是一些详细的信息和示例。 UPDATE语法: UPDATE 表
    的头像 发表于 11-21 11:29 4184次阅读

    sql where条件的执行顺序

    SQL语句中的WHERE条件是用来筛选数据的,它决定了哪些数据会被返回给用户。WHERE条件的执行顺序是影响SQL语句性能的一个重要因素,正
    的头像 发表于 11-23 11:31 2230次阅读

    oracle执行sql查询语句的步骤是什么

    Oracle数据库是一种常用的关系型数据库管理系统,具有强大的SQL查询功能。Oracle执行SQL查询语句的步骤包括编写SQL
    的头像 发表于 12-06 10:49 991次阅读

    Oracle如何执行sql脚本文件

    如何使用Oracle来执行SQL脚本文件。 一、什么是SQL脚本文件 SQL脚本文件是一个包含了一系列SQL
    的头像 发表于 12-06 10:51 6789次阅读

    单片机中for语句的运用

    语句,它的基本结构如下: for (初始化语句; 条件表达式; 更新语句) {循环体;} for语句执行
    的头像 发表于 01-05 14:02 2528次阅读