(转)一条SQL更新语句是如何执行的
名词
- MySQL 里经常说到的 WAL 技术,Write-Ahead Logging 第一个日志模块 redo log 也叫日志重写,是InnoDB 引擎特有的日志
- write pos and checkpoint
- crash-safe
- 另外一个日志模块binlog 归档日志,是server(功能层面)具有的日志 ## 参数
- innodb_flush_log_at_trx_commit redo log 用于保证 crash-safe 能力,innodb_flush_log_at_trx_commit=1,表示 表示每次事务的 redo log,都直接持久化到磁盘。这个参数我建议你设置成 1,这样可以保证 MySQL 异常重启,不会丢失数据
- sync_binlog 表示每次事务的 binlog 都持久化到磁盘,这个参数我也建议你设置成 1,这样可以保证 MySQL 异常重启,binlog日志不会丢失
执行update语句,innodb引擎干了什么
- prepare阶段
- 写binlog
- commit 阶段
当在2之前崩溃时,
重启恢复:后发现没有commit,回滚。备份恢复:没有binlog,两个log数据一致
当在3之前崩溃时,
重启恢复:虽没有commit,但满足prepare和binlog完整,所以重启后会自动commit。备份:有binlog,两个log数据 一致。
总结:一个事务正常执行是要commit 才算完,但是崩溃恢复过程的话,可以接受“redolog prepare 并且binlog完整” 的情况。
完整的一次update,数据库都干了什么
- 首先客户端通过tcp/ip发送一条sql语句到server层的SQL interface
- SQL interface接到该请求后,先对该条语句进行解析,验证权限是否匹配SQL interface接到该请求后,先对该条语句进行解析,验证权限是否匹配
- 验证通过以后,分析器会对该语句分析,是否语法有错误等验证通过以后,分析器会对该语句分析,是否语法有错误等
- 接下来是优化器器生成相应的执行计划,选择最优的执行计划接下来是优化器器生成相应的执行计划,选择最优的执行计划
- 之后会是执行器根据执行计划执行这条语句。在这一步会去open table,如果该table上有MDL,则等待。 如果没有,则加在该表上加短暂的MDL(S)之后会是执行器根据执行计划执行这条语句。在这一步会去open table,如果该table上有MDL,则等待。 如果没有,则加在该表上加短暂的MDL(S) (如果opend_table太大,表明open_table_cache太小。需要不停的去打开frm文件)
- 进入到引擎层,首先会去innodb_buffer_pool里的data dictionary(元数据信息)得到表信息进入到引擎层,首先会去innodb_buffer_pool里的data dictionary(元数据信息)得到表信息
- 通过元数据信息,去lock info里查出是否会有相关的锁信息,并把这条update语句需要的 锁信息写入到lock info里(锁这里还有待补充)通过元数据信息,去lock info里查出是否会有相关的锁信息,并把这条update语句需要的 锁信息写入到lock info里(锁这里还有待补充)
- 然后涉及到的老数据通过快照的方式存储到innodb_buffer_pool里的undo page里,并且记录undo log修改的redo (如果data page里有就直接载入到undo然后涉及到的老数据通过快照的方式存储到innodb_buffer_pool里的undo page里,并且记录undo log修改的redo (如果data page里有就直接载入到undo page里,如果没有,则需要去磁盘里取出相应page的数据,载入到undo page里)
- 在innodb_buffer_pool的data page做update操作。并把操作的物理数据页修改记录到redo log buffer里 由于update这个事务会涉及到多个页面的修改,所以redo log buffer里会记录多条页面的修改信息。在innodb_buffer_pool的data page做update操作。并把操作的物理数据页修改记录到redo log buffer里 由于update这个事务会涉及到多个页面的修改,所以redo log buffer里会记录多条页面的修改信息。因为group commit的原因,这次事务所产生的redo log buffer可能会跟随其它事务一同flush并且sync到磁盘上
- 同时修改的信息,会按照event的格式,记录到binlog_cache中。(这里注意binlog_cache_size是transaction级别的,不是session级别的参数, 同时修改的信息,会按照event的格式,记录到binlog_cache中。(这里注意binlog_cache_size是transaction级别的,不是session级别的参数,一旦commit之后,dump线程会从binlog_cache里把event主动发送给slave的I/O线程)
- 之后把这条sql,需要在二级索引上做的修改,写入到change buffer page,等到下次有其他sql需要读取该二级索引时,再去与二级索引做merge之后把这条sql,需要在二级索引上做的修改,写入到change buffer page,等到下次有其他sql需要读取该二级索引时,再去与二级索引做merge(随机I/O变为顺序I/O,但是由于现在的磁盘都是SSD,所以对于寻址来说,随机I/O和顺序I/O差距不大)
- 此时update语句已经完成,需要commit或者rollback。这里讨论commit的情况,并且双1此时update语句已经完成,需要commit或者rollback。这里讨论commit的情况,并且双1
- commit操作,由于存储引擎层与server层之间采用的是内部XA(保证两个事务的一致性,这里主要保证redo log和binlog的原子性), 所以提交分为prepare阶段与commit阶段commit操作,由于存储引擎层与server层之间采用的是内部XA(保证两个事务的一致性,这里主要保证redo log和binlog的原子性), 所以提交分为prepare阶段与commit阶段
- prepare阶段,将事务的xid写入,将binlog_cache里的进行flush以及sync操作(大事务的话这步非常耗时)prepare阶段,将事务的xid写入,将binlog_cache里的进行flush以及sync操作(大事务的话这步非常耗时)
- commit阶段,由于之前该事务产生的redo log已经sync到磁盘了。所以这步只是在redo log里标记commitcommit阶段,由于之前该事务产生的redo log已经sync到磁盘了。所以这步只是在redo log里标记commit
- 当binlog和redo log都已经落盘以后,如果触发了刷新脏页的操作,先把该脏页复制到doublewrite buffer里,把doublewrite buffer里的刷新到共享表空间,然后才是通过page cleaner线程把脏页写入到磁盘中.当binlog和redo log都已经落盘以后,如果触发了刷新脏页的操作,先把该脏页复制到doublewrite buffer里,把doublewrite buffer里的刷新到共享表空间,然后才是通过page cleaner线程把脏页写入到磁盘中
参考地址:https://blog.csdn.net/weixin_39602697/article/details/84863292
(转)一条SQL更新语句是如何执行的的更多相关文章
- 2 日志系统:一条sql更新语句是如何执行的?
2 日志系统:一条sql更新语句是如何执行的? 前面了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后达到e ...
- 02 | 日志系统:一条SQL更新语句是如何执行的? 学习记录
<MySQL实战45讲>02 | 日志系统:一条SQL更新语句是如何执行的? 学习记录http://naotu.baidu.com/file/ad320c7a0e031c2d6db7b5a ...
- 一条SQL更新语句是如何执行的
文章首发于公众号「蝉沐风」,认真写好每一篇文章,欢迎大家关注交流 这是图解MySQL的第2篇文章,这篇文章会通过一条SQL更新语句的执行流程让大家清楚地明白: 什么是InnoDB页?缓存页又是什么?为 ...
- 日志系统:一条sql更新语句是如何执行的?--Mysql45讲笔记记录 打卡day2
下面是一个表的创建语句,这个表有一个主键id和一个整型字段c: create table t(id int primary key,c int); 如果要将 id = 2 这一行的值加 1,sql语句 ...
- mysql实战45讲读书笔记(二) 一条SQL更新语句是如何执行的 极客时间
前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更新语 ...
- 《Mysql 一条 SQL 更新语句是如何执行的?(Redo log)》
一:更新流程 - 对于更新来说,也同样会根据 SQL 的执行流程进行. - - 连接器 - 连接数据库,具体的不做赘述. - 查询缓存 - 在一个表上有更新的时候,跟这个表有关的查询缓存会失效. - ...
- 02 | 日志系统:一条SQL更新语句是如何执行的?
前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更新语 ...
- mysql数据库系统学习(一)---一条SQL查询语句是如何执行的?
本文基于----MySQL实战45讲(极客时间----林晓斌 )整理----->https://time.geekbang.org/column/article/68319 一.第一节:一条sq ...
- 一文读懂一条 SQL 查询语句是如何执行的
2001 年 MySQL 发布 3.23 版本,自此便开始获得广泛应用,随着不断地升级迭代,至今 MySQL 已经走过了 20 个年头. 为了充分发挥 MySQL 的性能并顺利地使用,就必须正确理解其 ...
随机推荐
- $.post()参数及返回值
JQuery中的$.post()函数 先看一个例子:$.post("adduser.ashx", { "name": name, "sex" ...
- [docker]Kubernetes的yaml文件
yaml是一种专门用来写配置的语言,简洁强大 它的规则: 1.大小写敏感 2.使用缩进表示层级关系,但不支持tab缩进,只支持空格 3.缩进的数量不重要但至少一个空格,只要相同层级使用相同数量的空格即 ...
- HTTP协议相关介绍
一.HTTP请求方法 根据HTTP标准,HTTP请求可以使用多种请求方法.HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法.HTTP1.1新增了五种请求方法:OPTIONS, ...
- UIView的alpha、hidden和opaque属性之间的关系和区别[转]
UIView的alpha.hidden和opaque属性之间的关系和区别 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/ ...
- linq to sql 实现左(右)连接,那个方法是对的,该怎么处理
linq to sql 实现左(右)连接,那个方法是对的var query2 = from tb0 in db.table_0 join tb1 in db.table_1 on table_0.关 ...
- 对于网站,APP开发流程的理解
• 明确产品目标用户,目标市场 • 明确将要开发的产品面世后是要解决什么样的问题 • 梳理产品有哪些功能点,功能点如何按照模块划分 • 站在用户角度思考用户怎样使用这款产品,以故事的情景讲述用户如何使 ...
- Python&Django学习系列之-激活管理界面
1.创建你个人的项目与APP 2.填写你的数据库名称与数据库类型,这里使用内置的sqllite3 3.修改setting文件 a.将'django.contrib.admin'加入setting的IN ...
- Ubuntu下添加Python环境变量
最近把自己在windows上的Django项目放在的Ubuntu上,启动时提示找不到模块 原来是自己的项目用的是虚拟环境,安装的第三方库全部在虚拟环境中 AutoTestSite/venv/Lib/s ...
- angular OnChange事件
import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core'; @Component({ sel ...
- C# 调接口
上一个项目,需要mvc管理后台调接口项目,以便后期的重构扩展,调研后发现后台用的ajax请求,直接调接口可能会有跨域问题,最终在c#代码中实现了这个需求. 1,Ajax请求后台 将接口所需参数传入 2 ...