上一篇文章咱们说了一条查询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. 转 ORA-13541: system moving window baseline size (691200) greater than retention (432000)

    修改awr生成报告时间间隔和保存时间时报错,由默认的每小时生成,保存8天修改为每半个小时生成一次,保存5天: SQL> exec dbms_workload_repository.modify_ ...

  2. Django架站的16堂課

    Django架站的16堂課-活用Django+Web+Framework快速构建移动网站 目录 第1堂 网站开发环境的建立 1 1.1 网站的基础知识 1 1.1.1 网站的运行流程 1 1.1.2 ...

  3. 一份 Tomcat 和 JVM 的性能调优经验总结!拿走不谢

    Tomcat性能调优 找到Tomcat根目录下的conf目录,修改server.xml文件的内容.对于这部分的调优,我所了解到的就是无非设置一下Tomcat服务器的最大并发数和Tomcat初始化时创建 ...

  4. netty WEBSOKET 客户端 JAVA

    https://blog.csdn.net/mafei6827/article/details/80657405 https://blog.csdn.net/u010939285/article/de ...

  5. 如何关闭phpstrom的更新提醒?

    在file-----setting-------搜索updates 把检测版本更新的对勾点掉就可以了, 自己破解后的版本就别更新了,更新后就不能再用了,目前用代理服务器激活可以用版本3.3,升级到3. ...

  6. 【Leetcode_easy】977. Squares of a Sorted Array

    problem 977. Squares of a Sorted Array solution: class Solution { public: vector<int> sortedSq ...

  7. CSS Position定位过多是否会影响浏览器渲染速度

    一直有个传说就是页面里的Position多了会影响浏览器渲染速度,今天做个测试看看结果如何. 检验的方法: 动态创建一定数量的div > 开始计算时间 > 导入css文件渲染 > o ...

  8. 海思NB-IOT模组在平台上注册

    1. 添加设备,网页测试平台 https://develop.ct10649.com:8093/#/applications/1_lq7clNExjnGvPvGMG8w7_oYn4a/products ...

  9. python解析本地HTML文件

    Python使用爬虫技术时,每运行一次,本地都会访问一次主机.为避免完成程序前调试时多次访问主机增加主机负荷,我们可以在编写程序前将网页源代码存在本地,调试时访问本地文件即可.现在我来分享一下爬取资料 ...

  10. ubuntu 安装 iperf

    iperf的github https://github.com/esnet/iperf/releases 解压 sudo tar -zvxf iperf-3.6.tar.gz -C /usr/loca ...