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 ...
随机推荐
- centos7 安装部署zabbix客户端
1.下载安装zabbix-agent: # rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2. ...
- matlab 正弦信号产生
fs=2400;%设定采样频率N=1000; %采样的点数n=0:N-1;t=n/fs; %1/fs相当于隔多长时间才一个点f1=50;%设定争先信号频率xn=sin(2*pi*f1*t);figur ...
- Librepilot-Windows编译环境的搭建
1.安装Msys2 下载Msys2,下载地址 https://msys2.github.io,注意根据笔记本的型号选择32bit或64bit. 2.添加LibrePilot MinGW库 在 /e ...
- idea 新手入门配置
1.配置新建类时,创建者信息 2.配置svn 1. 在idea中不显示无用的内容,配置如下 .hprof;.iml;.pyc;.pyo;.rbc;.yarb;~;.DS_Store;.git;.hg ...
- Solaris 11中配置基于link的IPMP
http://blog.itpub.net/29960937/viewspace-1347901/ Tips: Record and feedback errors you have encounte ...
- Redux 聊聊
前言 Redux 是 JavaScript 状态容器,提供可预测化的状态管理. 首先明确一点的就是: Redux并不是React必须的,也没有任何依赖,你可以很自由的将他应用到各种前端框架.jQuer ...
- 理解 es7 async/await
简介 JavaScript ES7 中的 async / await 让多个异步 promise 协同工作起来更容易.如果要按一定顺序从多个数据库或者 API 异步获取数据,你可能会以一堆乱七八糟的 ...
- caffe的网络层结构(1)
1.concat层 该层有两个相同作用的参数: message ConcatParameter { //指定拼接的维度,默认为1即以channel通道进行拼接;支持负索引,即-1表示最后一个维度 op ...
- Java设计模式:23种设计模式全面解析(超级详细)
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健性以及安全性的解决方案. 1995 ...
- 使用vscode打断点
1.vscode打开的文件必须只包含你要调适的项目,不能同时在一个vscode打开多个项目窗口 2.点击vscode的这个小蜘蛛 3.选择添加配置 4.此时自动生成了一个文件,launch.json: ...