【大厂面试04期】讲讲一条MySQL更新语句是怎么执行的?
流程图
这是在网上找到的一张流程图,写的比较好,大家可以先看图,然后看详细阅读下面的各个步骤。

执行流程:
1.连接验证及解析
客户端与MySQL Server建立连接,发送语句给MySQL Server,接收到后会针对这条语句创建一个解析树,然后进行优化,(解析器知道语句是要执行什么,会评估使用各种索引的代价,然后去使用索引,以及调节表的连接顺序)然后调用innodb引擎的接口来执行语句。
2.写undo log
innodb 引擎首先开启事务,对旧数据生成一个UPDATE的语句(如果是INSERT会生成UPDATE语句),用于提交失败后回滚,写入undo log,得到回滚指针,并且更新这个数据行的回滚指针和版本号(会设置为更新的事务id)。
3.从索引中查找数据
根据查询条件去B+树中找到这一行数据(如果是唯一性索引,查到第一个数据就可以了(因为有唯一性约束),如果是普通索引,会把所有数据查找出来。)
4.更新数据
首先判断数据页是否在内存中?
4.1 如果数据页在内存中
先判断更新的索引是普通索引还是唯一性索引?
4.1.1 普通索引
如果更新的索引是普通索引,直接更新内存中的数据页
4.1.2 唯一性索引
如果更新的索引是唯一性索引,判断更新后是否会破坏数据的唯一性,不会的话就更新内存中的数据页。
4.2 如果数据页不在内存中
先判断更新的索引是普通索引还是唯一性索引?
4.2.1 普通索引
如果是更新的索引是普通索引,将对数据页的更新操作记录到change buffer,change buffer会在空闲时异步更新到磁盘。
4.2.2 唯一性索引
如果是更新的索引是唯一性索引,因为需要保证更新后的唯一性,所以不能延迟更新,必须把数据页从磁盘加载到内存,然后判断更新后是否会数据冲突,不会的话就更新数据页。
5.写undo log(prepare状态)
将对数据页的更改写入到redo log,将redo log设置为prepare状态。
6.写bin log(commit状态),提交事务
通知MySQL server已经更新操作写入到redo log 了,随时可以提交,将执行的SQL写入到bin log日志,将redo log改成commit状态,事务提交成功。(一个事务是否执行成功的判断依据是是否在bin log中写入成功。写入成功后,即便MySQL Server崩溃,之后恢复时也会根据bin log, redo log进行恢复。具体可以看看下面的崩溃恢复原则)
补充资料:
二段提交制是什么?
更新时,先改内存中的数据页,将更新操作写入redo log日志,此时redo log进入prepare状态,然后通知MySQL Server执行完了,随时可以提交,MySQL Server将更新的SQL写入bin log,然后调用innodb接口将redo log设置为提交状态,更新完成。
如果只是写了bin log就提交,那么忽然发生故障,主节点可以根据redo log恢复数据到最新,但是主从同步时会丢掉这部分更新的数据。
如果只是写binlog,然后写redo log,如果忽然发生故障,主节点根据redo log恢复数据时就会丢掉这部分数据。
MySQL崩溃后,事务恢复时的判断规则是怎么样的?(以redolog是否commit或者binlog是否完整来确定)
如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;
如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:a. 如果是,则提交事务;b. 否则,回滚事务。
undo log是什么?
undo log主要是保证事务的原子性,事务执行失败就回滚,用于在事务执行失败后,对数据回滚。undo log是逻辑日志,记录的是SQL。(可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。)
在事务提交后,undo log日志不会立即删除,会放到一个待删除的链表中,有purge线程判断是否有其他事务在使用上一个事务之前的版本信息,然后决定是否可以清理,简单的来说就是前面的事务都提交成功了,这些undo才能删除。
change buffer是什么(就是将更新数据页的操作缓存下来)
在更新数据时,如果数据行所在的数据页在内存中,直接更新内存中的数据页。
如果不在内存中,为了减少磁盘IO的次数,innodb会将这些更新操作缓存在change buffer中,在下一次查询时需要访问这个数据页时,在执行change buffer中的操作对数据页进行更新。
适合写多读少的场景,因为这样即便立即写了,也不太可能会被访问到,延迟更新可以减少磁盘I/O,只有普通索引会用到,因为唯一性索引,在更新时就需要判断唯一性,所以没有必要。
redo log 是什么?
redo log就是为了保证事务的持久性。因为change buffer是存在内存中的,万一机器重启,change buffer中的更改没有来得及更新到磁盘,就需要根据redo log来找回这些更新。
优点是减少磁盘I/O次数,即便发生故障也可以根据redo log来将数据恢复到最新状态。
缺点是会造成内存脏页,后台线程会自动对脏页刷盘,或者是淘汰数据页时刷盘,此时收到的查询请求需要等待,影响查询。
【大厂面试04期】讲讲一条MySQL更新语句是怎么执行的?的更多相关文章
- 2 日志系统:一条sql更新语句是如何执行的?
2 日志系统:一条sql更新语句是如何执行的? 前面了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后达到e ...
- 02 | 日志系统:一条SQL更新语句是如何执行的? 学习记录
<MySQL实战45讲>02 | 日志系统:一条SQL更新语句是如何执行的? 学习记录http://naotu.baidu.com/file/ad320c7a0e031c2d6db7b5a ...
- 一条SQL更新语句是如何执行的
文章首发于公众号「蝉沐风」,认真写好每一篇文章,欢迎大家关注交流 这是图解MySQL的第2篇文章,这篇文章会通过一条SQL更新语句的执行流程让大家清楚地明白: 什么是InnoDB页?缓存页又是什么?为 ...
- mysql实战45讲读书笔记(二) 一条SQL更新语句是如何执行的 极客时间
前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更新语 ...
- 《Mysql 一条 SQL 更新语句是如何执行的?(Redo log)》
一:更新流程 - 对于更新来说,也同样会根据 SQL 的执行流程进行. - - 连接器 - 连接数据库,具体的不做赘述. - 查询缓存 - 在一个表上有更新的时候,跟这个表有关的查询缓存会失效. - ...
- 日志系统:一条sql更新语句是如何执行的?--Mysql45讲笔记记录 打卡day2
下面是一个表的创建语句,这个表有一个主键id和一个整型字段c: create table t(id int primary key,c int); 如果要将 id = 2 这一行的值加 1,sql语句 ...
- 02 | 日志系统:一条SQL更新语句是如何执行的?
前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更新语 ...
- (转)一条SQL更新语句是如何执行的
名词 MySQL 里经常说到的 WAL 技术,Write-Ahead Logging 第一个日志模块 redo log 也叫日志重写,是InnoDB 引擎特有的日志 - write pos and c ...
- 【大厂面试02期】Redis过期key是怎么样清理的?
PS:本文已收录到1.1K Star数开源学习指南--<大厂面试指北>,如果想要了解更多大厂面试相关的内容,了解更多可以看 http://notfound9.github.io/inter ...
随机推荐
- mybatis-generator生成的mapper中的
int updateByExampleSelective(@Param("record") Shop record, @Param("example") Sho ...
- docker容器与系统时间同步最佳方法
前言:在Docker容器创建好之后,可能会发现容器时间跟宿主机时间不一致,此时需要同步它们的时间,让容器时间跟宿主机时间保持一致. 一.分析时间不一致的原因 宿主机采用了CST时区,CST应该是指(C ...
- .NET 程序员的 Playground :LINQPad
如果想执行一个简单的 C# 语句并获得运行结果,通常我们需要做几个步骤才能达成: 打开 Visual Studio 并新建一个控制台项目. 在 Program.cs 中编写代码并保存. 点击运行按钮或 ...
- npm加载包报错 :syscall access
$ npm install --save-dev babel-plugin-syntax-dynamic-import npm WARN checkPermissions Missing write ...
- Vue与 Vue组件部分
1.Vuex作用?哪种功能场景使用它? 答案:vue框架中状态管理. 场景有:单页面应用中,组件之间的状态.音乐播放. 登录状态.加入购物车 2.解释vuex最常用的两种属性 答案:分别State.G ...
- Django之forms.ModelForm
通常在Django项目中,我们编写的大部分都是与Django 的模型紧密映射的表单. 举个例子,你也许会有个Book 模型,并且你还想创建一个form表单用来添加和编辑书籍信息到这个模型中. 在这种情 ...
- Scaner对象
目录 Scaner的基本概念 基本语法: 1.使用next() 的方式来接收字符串(使用频率较少) 2.使用nextLine()的方式来接收字符串 进阶使用(练习题) Scaner的基本概念 之前我们 ...
- 201771010128 王玉兰《面象对象程序设计(Java)》第六周学习总结
第一部分:基础知识总结: 1.继承 A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况: B:特点:具有层次结构.子类继承父类的方法和域: ...
- 浅析String、StringBuilder、StringBuffer
谈谈我对 String.StringBuilder.StringBuffer 的理解 StringBuilder.StringBuffer 和 String 一样,都是用于存储字符串的. 1.那既然有 ...
- Liquibase使用小结
简介 Liquibase是一个用于跟踪.管理和应用数据库变化的开源数据库重构工具.它将所有数据库的变化保存在XML文件中,便于版本控制和项目部署升级.在快速搭建项目的JHipster框架中集成了该工具 ...