(转)一条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 的性能并顺利地使用,就必须正确理解其 ...
随机推荐
- 关于 Azure 安全性的 10 点提示
讨论云服务时,安全性是一个关键领域.实际上,Windows Azure 基础结构实施大量的技术和流程来保护环境.此页介绍 Microsoft 的全球基础服务如何运行基础结构以及它们实施的安全措施. 从 ...
- Java 线程不安全问题分析
当多个线程并发访问同一个资源对象时,可能会出现线程不安全的问题 public class Method implements Runnable { private static int num=50; ...
- c#缓存介绍
#缓存介绍(转) 本章导读 缓存主要是为了提高数据的读取速度.因为服务器和应用客户端之间存在着流量的瓶颈,所以读取大容量数据时,使用缓存来直接为客户端服务,可以减少客户端与服务器端的数据交互,从而大大 ...
- [web] [vscode] 自定义语言缩进
vscode 默认的html 语言的缩进有点过,貌似一个tab6个space, html看起来太空了,所幸的是可以自己调整单个语言的缩进模式. 方法如下 Preferences: Open User ...
- vs2010 在win8附加进程调试小技巧
在win8 附加进程居然找不到 我要的是iis 名为HKFlight的web的进程(下面2个勾也勾上了,就是找不到它)(下图是管理员身份运行截图) 解决方法:打开vs2010 用管理员身份打开...其 ...
- 深入解析mapreduce 笔记
Hadoop组成: mapreduce简单介绍: 伪代码演示: maptask和reducetask执行流程:
- "window.location.href"、"location.href"是本页面跳转
"window.location.href"."location.href"是本页面跳转 "parent.location.href"是上一 ...
- 写excel
一.写excel import xlwt book = xlwt.Workbook()# 创建excel sheet = book.add_sheet('stu_info')# 加一个sheet sh ...
- 【ARC069F】Flags 2-sat+线段树优化建图+二分
Description 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input 第一行一个整数 N. 接下来 N 行每行两个整数 xi, ...
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication(最小割)
题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...