上一篇文章咱们说了一条查询sql的执行过程。如果没有看过上一篇文章的可以去看下上一篇文章,今天咱们说说一条更新sql的执行过程。

update scores set  score=c+10 where id=1

上面一条sql是将id为1的分数加上10。

那么它的执行流程是怎样的呢?借用上篇文章的图,如下:

我这边就再简单的说一下这个流程,首先客户端连接mysql服务器,连接后执行sql语句,执行sql的过程需要经过分析器得出它是需要做update操作,再接着经过优化器它决定使用id这个索引,然后经过执行器通过索引找到这一行,最后进行更新操作。

以上就是整个更新操作得整个流程。说到这你肯定以为说完了,不过很遗憾的告诉你,这才刚刚开始呢。

因为更新操作和查询操作不一样,更新操作涉及到两个非常重要的日志模块。redo log (重做日志) 和 bin log(归档日志)。这个两个才是今天要说的重点。

首先咱们得知道这两个日志是什么?然后再得知道它们是干什么的?

redo log 是 InnoDB 引擎特有,它是属于物理日志,主要用于记录 “某个数据页上做了什么修改” ,而且它的记录空间是固定的并且是会用完的。

bin log 是属于 server 层持有的,主要是再执行器中记录日志,所以mysql所有的引擎都可以使用它。bin log 是属于逻辑日志,它有 statement 和 row 两种模式,statement记录的是执行的sql语句,row记录的是更新行的内容,所以是记录两条,一条是更新前的内容,另外一条是更新后的内容。默认模式是 row 模式。另外 bin log 是会追加写入日志,当日志文件写到一定大小的时候,就会切换到下一个继续写入日志,并且不会覆盖之前的日志文件。

以上就是这两种日志的概念以及作用,那么现在我们说说它们的记录流程。咱们先看下面一张图,黄填充色的为执行器的操作,蓝填充色为InnoDB引擎的操作

图有点长,不过应该很容易看懂。那么现在就来一步一步的分析。

1、首先执行器会找引擎取id=1这条数据;

2、因为id是主键,所以使用树来找到一行数据。不过引擎先去内存中查找是否有这一页数据;

3、如果有则直接返回数据给执行器;如果没有就会去磁盘把数据读入到内存中,然后返回数据给执行器。

4、执行器就会执行C+10操作;

5、执行器生成新的一行数据;

6、再调用 InnoDB 引擎的写入接口,把数据更新到内存中;

7、InnoDB 引擎写入 redo log 日志,标记状态为 prepare,并且告诉执行器已经更新数据完成,可以随时提交事务;

8、执行器把此操作写入 bin log ,并且把 bin log 写入磁盘;

9、最后执行器调用引擎的提交事务接口,引擎把 redo log 的状态改 commit ,至此整个更新操作完成。

看到这里也许你会冒出几个问题?

1、redo log 空间是固定,那它会不会用完呢?

首先不用担心 redo log 会用完空间,因为它是循环利用的。例如 redo log 日志配置为一组4个文件,每个文件分别为1G。它写的流程如下图:

上图中有两块填充色,黄色和红色,黄色标记着 check point,这表示这当前擦除掉 redo log 的位置,红色标记着 write pos ,这表示着当前记录 redo log 的位置。当 redo log 写满了之后,就会停下来,不再写入数据,会执行擦除 redo log 操作,当然在擦除这些日志之前,都会把数据写入到磁盘中,把数据进行持久化。这样才能保住数据的准确性。

2、为什么要用这两种日志呢?因为在没有 InnoDB 引擎的时候是没有 redo log 日志的。

因为 InnoDB 引擎的 redo log 可以保证即使数据库突然宕机了或者异常重启了,之前提交的数据是不会丢失的。这个能力咱们称之为 crash-safe。

3、当mysql服务器在执行过程中突然间宕机了,数据会不会丢失?

答案是不会。为什么这么肯定呢?我们可以从第二张图就可以看出来。比如有以下几种情况:

1、写入 redo log 之前宕机了,那么原始数据是不会发送改变的,因为还没有进行事务的提交。

2、如果写入 redo log 之后,写入 bin log之前宕机,那么原始数据还是不会变,因为数据库重启后,因为两种日志的记录没有同步,所以不会有新数据生成。

3、在 redo log 生成commit之前宕机了,数据库重启后 数据会变成更新后的数据,因为这个时候 redo log 和 bin log 都有了记录,所以数据库重启后会自己进行commit,所以这时候的数据就是更新后的数据了。

我们使用 redo log 主要是需要保证 crash-safe 能力,innodb_flush_log_at_trx_commit这个参数设置成1的时候,表示每次事务的redo log都直接持久化到磁盘。这个参数我建议你设置成1,这样可以保证MySQL异常重启之后数据不丢失。

sync_binlog这个参数设置成1的时候,表示每次事务的binlog都持久化到磁盘。这个参数我也建议你设置成1,这样可以保证MySQL异常重启之后binlog不丢失。

好了,今天就说到这里,如果写的有误的地方欢迎大家指出,咱们一起讨论学习。

MySql 学习之 一条更新sql的执行过程的更多相关文章

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

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

  2. mybatis源码学习(二):SQL的执行过程

    从上一篇文章中,我们了解到MapperMethod将SQL的执行交给了sqlsession处理.今天我们继续往下看处理的过程. SqlSession接口除了提供获取Configuration,Mapp ...

  3. 一条更新SQL的内部执行及日志模块

    一条更新SQL的内部执行 学习MySQL实战45讲,非常推荐学 还是老图: 上文复习 在执行查询语句的时候,会执行连接器(总要连上才能搞事情),然后去查询缓存(MySQL8+删除了),有数据返回,没数 ...

  4. mysql体系结构和sql查询执行过程简析

    一: mysql体系结构 1)Connectors 不同语言与 SQL 的交互 2)Management Serveices & Utilities 系统管理和控制工具 备份和恢复的安全性,复 ...

  5. Oracle是如何工作的?实例是如何响应用户请求?一条SQL的执行过程~

    Oracle 是如何工作的? Select id,name from t order by id ; – SQL 解析(查看语法是否错误,如果没有错误,分析语意,执行此语句的权限) – 执行计划(OR ...

  6. mybatis源码分析(五)------------SQL的执行过程

    在对SQL的执行过程进行分析前,先看下测试demo: /** * @author chenyk * @date 2018年8月20日 */ public class GoodsDaoTest { pr ...

  7. 转:Oracle中SQL语句执行过程中

    Oracle中SQL语句执行过程中,Oracle内部解析原理如下: 1.当一用户第一次提交一个SQL表达式时,Oracle会将这SQL进行Hard parse,这过程有点像程序编译,检查语法.表名.字 ...

  8. 深入学习MySQL 01 一条查询语句的执行过程

    在学习SpringCloud的同时,也在深入学习MySq中,听着<mysql45讲>,看着<高性能MySQL>,本系列文章是本人学习过程的总结,水平有限,仅供参考,若有不对之处 ...

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

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

随机推荐

  1. synchronized 同步对象概念

    解决上述问题之前,先理解synchronized关键字的意义如下代码:   Object someObject =new Object(); synchronized (someObject){ // ...

  2. 数据结构与抽象 Java语言描述 第4版 pdf (内含标签)

    数据结构与抽象 Java语言描述 第4版 目录 前言引言组织数据序言设计类P.1封装P.2说明方法P.2.1注释P.2.2前置条件和后置条件P.2.3断言P.3Java接口P.3.1写一个接口P.3. ...

  3. IE浏览器提示打印控件未安装的一些原因

    打印控件未安装!点击这里执行安装,安装后请刷新页面或重新进入.--该提示是写在LodopFuncs.js里的.相关本博客其他博文:提示“Web打印服务CLodop未安装启动”的各种原因和解决方法.C- ...

  4. linux如何找回已经删除的文件?lsof

    简介 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控 ...

  5. 管道式编程(Pipeline Style programming)

    受 F# 中的管道运算符和 C# 中的 LINQ 语法,管道式编程为 C# 提供了更加灵活性的功能性编程.通过使用 扩展函数 可以将多个功能连接起来构建成一个管道. 前言 在 C# 编程中,管道式编程 ...

  6. 推荐linux运维必备的几本书

    首先,<鸟哥的linux私房菜> 鸟哥 其次,<linux就该这么学> 刘瑞版 然后,<CentOS linux系统运维> 张祥琳版 最后,<CentOS运维 ...

  7. linux maven环境变量配置

    export MAVEN_HOME=/opt/hjyang/soft/maven export MAVEN_HOME export PATH=$PATH:$MAVEN_HOME/bin

  8. java学习笔记(7)--链表

    标签(空格分隔):笔记 java其实已经将很多底层的数据结构进行了封装,虽然工作用不到,但是笔试和面试问的还是比较频繁的,而且这种面试题还是直接手撕代码,故专门总结一下. 1. 概念 1.1 链表(L ...

  9. Java后台面试之java基础

    经典类概念性问题 1.java支持的数据类型有哪些?什么是自动拆装箱? 12.Java有哪些特性,举个多态的例子. 14.请列举你所知道的Object类的方法. 15.重载和重写的区别?相同参数不同返 ...

  10. Hystrix【入门】

    公共依赖配置: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spr ...