2 日志系统:一条sql更新语句是如何执行的?
2 日志系统:一条sql更新语句是如何执行的?
前面了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后达到engine。
这里分析一个update语句的流程
mysql> create table T(ID int primary key, c int);
更新语句
mysql> update T set c=c+1 where ID=2;
查询语句的那一套流程,更新语句也是同样会走一遍
执行语句前要先连接db--连接器的工作
在一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表T上所有缓存结果都清空--不建议使用查询缓存的原因
接下来,分析器会通过词法和语法分析知道这是一条update语句,优化器决定使用id这个索引,然后执行器负责具体执行,找到这一行,然后update
与查询流程不一样的,更新流程还涉及两个重要的日志模块:redo log和binlog
redo log
在mysql里,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到那条对应的记录,然后再更新,整个过程io成本、查找成本都很高,为了解决这个问题,在mysql里使用WAL,write-ahead loggin,日志先行,关键点就是先写日志、再写磁盘。
当有一条记录需要更新的时候,innodb引擎就会先把记录写到redo log,并更新内存,这个时候更新就算完成了。同时,innodb引擎会在适当的时候,将这个记录更新到磁盘里面。
Innodb的redo log是固定大小,从头开始,写到末尾就又回到开头循环写,有了redo log,innodb就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个功能称为crash-safe。
binlog
从mysql整体来看,一块是server层,主要是mysql功能层面的事情;另一块是引擎层,负责存储相关的具体事宜,redo log就是innodb特有的日志,而server层的日志,就是binlog。
两种日志的不同点
--1 redo log是innodb引擎特有的,binlog是mysql server层实现的,所有引擎都可以使用。
--2 redo log是物理日志,记录的是”在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑。
--3 redo log是循环写的,空间固定;binlog是可以追加写入的,binlog文件写到一定大小后会切换到下一个,并不会覆盖之前的日志
更新update的流程
--1 执行器找到engine取id=2的这一行,id是主键,engine直接用树搜索找到这一行,如果id=2这一行所在的数据本来就在内存中,就直接返回给执行器,否则,需要先从磁盘读入内存,然后再返回。
--2 执行器拿到engine给的行数据,把这个值加上1,比如是n>n+1,得到新的一行数据,在调用引擎接口写入这行新数据
--3 engine将这行新数据更新到内存中,同时将这个更新操作记录到redo log里面,此时redo log处于prepare状态,然后告知执行器完成了,随时可以提交事务
--4 执行器生成这个操作的binlog,并把binlog写入磁盘
--5 执行器调用引擎的提交事务接口,engine把刚刚写入的redo log改成提交(commit)状态,更新完成。
两阶段提交
怎样让数据库恢复到7天内任意一秒的状态?
binlog会记录所有的逻辑操作,并且是采用追加写的形式,如果保存了最近一个月的binlog,同时系统有定期的整库备份,当需要恢复到指定的某一秒时,比如某条下午两点发现中午十二点有一次误删表,需要找回数据,可以这么做:
--1 找到最近一次的全备份,如果运气好,可能就是昨晚上的一个备份,从这个备份恢复到临时库
--2 从备份的时间点开始,将备份的binlog依次取出来,重放到中午误删表之前的那个时刻。
这样临时库就跟误删之前的线上一样,然后可以把表数据从临时库取出来,按需要恢复到线上库去。
由于redo log和binlog是两个独立的逻辑,如果不用两阶段提交,要么是先写完redo log再写binlog,或者反过来的顺序,看看有什么问题
--1 先写redo log后写binlog。假设redo log完成,binlog还没有写完,mysql异常重启,由于redo log写完之后,即使系统崩溃,已让能够把数据恢复。
但是由于binlog没写完就crash,这时候binlog没有这条update语句,之后备份日志的时候,存起来的binlog就没有这条语句,如果用binlog恢复的话,就会丢失之前的更新。
--2先写binlog后写redo log。如果在binlog之后carsh,还没来得及写redo log,崩溃恢复后这个update更新就无效,但是binlog里面已经记录了更新,这样用binlog来进行恢复就会导致不一致,同时也会导致备库的不一致。
简单说,redo log和binlog都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。
redo log用于保证crash-safe的能力,innodb_flush_log_at_trx_commit=1表示每次事务的redo log都直接持久化到磁盘,建议设置为1。sync_binlog=1,表示每次事务的binlog都持久化到磁盘,也建议设置为1.--双1模式
2 日志系统:一条sql更新语句是如何执行的?的更多相关文章
- 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语句 ...
- 02 | 日志系统:一条SQL更新语句是如何执行的?
前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更新语 ...
- mysql实战45讲读书笔记(二) 一条SQL更新语句是如何执行的 极客时间
前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更新语 ...
- 《Mysql 一条 SQL 更新语句是如何执行的?(Redo log)》
一:更新流程 - 对于更新来说,也同样会根据 SQL 的执行流程进行. - - 连接器 - 连接数据库,具体的不做赘述. - 查询缓存 - 在一个表上有更新的时候,跟这个表有关的查询缓存会失效. - ...
- (转)一条SQL更新语句是如何执行的
名词 MySQL 里经常说到的 WAL 技术,Write-Ahead Logging 第一个日志模块 redo log 也叫日志重写,是InnoDB 引擎特有的日志 - write pos and c ...
- 一文读懂一条 SQL 查询语句是如何执行的
2001 年 MySQL 发布 3.23 版本,自此便开始获得广泛应用,随着不断地升级迭代,至今 MySQL 已经走过了 20 个年头. 为了充分发挥 MySQL 的性能并顺利地使用,就必须正确理解其 ...
- mysql数据库系统学习(一)---一条SQL查询语句是如何执行的?
本文基于----MySQL实战45讲(极客时间----林晓斌 )整理----->https://time.geekbang.org/column/article/68319 一.第一节:一条sq ...
随机推荐
- ansible获取远程机器上的ip地址
问题: 想要使用ansible-playbook脚本创建一个以远程机器的IP命名的目录 错误的代码:# vim test.yml --- - hosts: all remote_user: root ...
- AUC计算方法
本质是ROC曲线下的面积,ROC曲线x轴是误判率/误报率(false positive rate),y轴是准确率/命中率(true positive rate). AUC是ROC曲线与横轴所围的面积. ...
- ARM仿真器之驱动黄色惊叹号
JLink CDC UART PORT 黄色惊叹号 Windows 无法验证此设备所需的驱动程序的数字签名.某软件或硬件最近有所更改,可能安装了签名错误或损毁的文件,或者安装的文件可能是来路不明的恶意 ...
- bootstrap-table(2)问题集
参考;https://www.cnblogs.com/landeanfen/p/4993979.html 1.分页参数sidePagination 如果是服务端分页,返回的结果必须包含total.ro ...
- 【bzoj2300】【Luogu P2521】 [HAOI2011]防线修建 动态凸包,平衡树,Set
一句话题意:给你一个凸包,每次可以插入一个点或者询问周长. 动态凸包裸题嘛,用\(Set\)实现.最初每个点坐标做乘三处理,便于取初始三角形的重心作为凸包判定原点. #include <bits ...
- ax2+bx+c=0的根的算法
每日一练作业 写一个函数,接受三个整数a, b, c,计算ax2+bx+c=0 的根. 另外,在计算时应当判断 b2 - 4ac 是否大于0. 我们什么都没有,唯一的本钱就是青春.梦想让我与众不同,奋 ...
- Linux 软件的下载安装
一.Linux系统安装软件的方式有两种: 1.通过 Linux 资源服务(类似于APP Shop)直接安装 2.下载tar包,解压安装. 二.Linux 资源服务安装软件 1.提示:一般安装一个软 ...
- springboot扫描自定义的servlet和filter代码详解_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 这几天使用spring boot编写公司一个应用,在编写了一个filter,用于指定编码的filter,如下: /** ...
- A1006
输入n行员工id以及到达和离开的时间,输出最早到达的员工的id和最晚离开的员工的id 注:字符串赋值函数strcpy(目标字符串,原字符串)字符串之间的赋值使用该函数,需要#include<st ...
- CF1257E/F
E 给出三个序列共n个元素,每个元素值为1~n且不重 一次可以把一个元素换到另一个序列中,求最少操作次数使得三个序列(可为空)分别排序后并在一起为1~n顺序 题解 (伪)神仙题 随便dp,依次考虑每个 ...