一条更新SQL的内部执行及日志模块
一条更新SQL的内部执行
学习MySQL实战45讲,非常推荐学
还是老图:
上文复习
在执行查询语句的时候,会执行连接器(总要连上才能搞事情),然后去查询缓存(MySQL8+删除了),有数据返回,没数据进行分析器-优化器-执行器-执行引擎流程并且其特点是如果该表上有更新,都会把缓存结果清空;
MySQL整体来看可以分为两块:一块是Server层,它主要做的是MySQL功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜;
update T set c=c+1 where ID=2;
流程:
- 连接器:连接数据库
- 分析器:分析词法和语法解析知道这是更新语句
- 优化器:决定使用ID进行索引
- 执行器:具体执行,找到改行然后更新
更新对查询来说,涉及到了两个重要的日志模块,redo log(重做日志)InnoDB特有的,binlog(归档日志)Server中存在的,只要持续学习数据库方面,这两个是绕不过的。
redo log(重做日志)
在InnoDB中redo log的大小是固定的,可以配置为一组4个文件,每个文件的大小是1GB,那么这块redo log总共就可以记录4GB的操作(可以自己设置)。
MySQL中的问题:
如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程IO成本、查找成本都很高
解决问题:
WAL技术:Write-Ahead Logging
- 写日志
- 写磁盘
执行流程:

为什么redo log具有crash-safe的能力
为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?
redo log的被动刷盘机制
明确定义:
write:刷盘
fsync:持久化到磁盘
write(刷盘)指的是MySQL从buffer pool中将内容写到系统的page cache中,并没有持久化到系统磁盘上。这个速度其实是很快的。
fsync指的是从系统的cache中将数据持久化到系统磁盘上。这个速度可以认为比较慢,而且也是IOPS升高的真正原因。
redo log是物理日志,记录的是“在某个数据页上做了什么修改”,内部结构是基于页的,记录了这个页的字段值变化,只要crash后读取redo log进行重放就可以恢复数据。(因为redo log是循环写的,如果满了InnoDB就会执行真正写盘)。
好处是不用每一次操作都实时把数据写盘,就算crash后也可以通过redo log重放恢复,所以能够实现快速响应SQL语句。
binlog(归档日志)
MySQL刚开始是使用的自带引擎MyISAM,但其没有crash-safe,binlog日志只能用于归档,5.5版本之后引入InnoDB,通过redo log来实现crash-safe能力。
redo log与binlog的区别
- redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
- redo log 是
物理日志,记录的是在某个数据页上做了什么修改;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。 - redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志
update内部执行流程:

流程图:图中浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的

其中redo log分为两个阶段提交:这是为了让两份日志之间的逻辑一致
- redo log prepare阶段
- commit阶段
好处:保证redo log和binlog都能同时失败或者成功。
论证两阶段提交的必要性:
如果不采用两阶段提交,那么redo log和binlog是单独的逻辑,由此引出下面两种提交方式:
- 先写redo log,后写binlog
- 先写binlog,后写redo log
还是以update为例:
update T set c=c+1 where ID=2;
先写redo log,后写binlog
在redo log写完,binlog没写完的时候,MySQL 进程异常重启,因为其实先写入内存的,所以MySQL崩溃后仍然能把数据恢复
根据备份恢复后c的值为1.但由于binlog没有写完就崩溃了,这时候binlog就没有记录这条语句的操作,使用binlog恢复的时候就会少一次更新,c的值为0,这就与原库的值不同了。
先写binlog,后写redo log与上面逻辑相同都会造成恢复的数据与原库值不同;
可以看到,如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致
但是当按照上述流程图来说,在进行两阶段提交的时候,即A、B时刻出现crash,是怎么处理的。
流程如下:

B时刻发生crash后对应的是2(a)的情况,崩溃恢复过程中事务会被提交。
由此引出的很多问题,感兴趣的朋友可以看下MySQL实战45讲答疑篇第一章
备份的流程:
- 找到最近的一次全量备份,从这个备份恢复到临时库;
- 从备份的时间点开始,将备份的 binlog 依次取出来,重放到中午误删表之前的那个时刻。
备份恢复的数据的场景:
- 误操作后需要恢复数据
- 要扩容的时候,也需要再多搭建一些备库来增加系统的读能力的时候,用全量备份加上应用binlog 来实现的。如果这个“不一致”就会导致你的线上出现主从数据库不一致的情况
一条更新SQL的内部执行及日志模块的更多相关文章
- JAVA中处理事务的程序--多条更新SQL语句的执行(包括回滚)
在与数据库操作时,如果执行多条更新的SQL语句(如:update或insert语句),在执行第一条后如果出现异常或电脑断电, 则后面的SQL语句执行不了,这时候设定我们自己提交SQL语句,不让JDBC ...
- MySql 学习之 一条更新sql的执行过程
上一篇文章咱们说了一条查询sql的执行过程.如果没有看过上一篇文章的可以去看下上一篇文章,今天咱们说说一条更新sql的执行过程. 上面一条sql是将id为1的分数加上10. 那么它的执行流程是怎样的呢 ...
- MySQL中一条更新语句是如何执行的
1.创建表的语句和更新的语句 这个表的创建语句,这个表有一个主键ID和一个整型字段c: mysql> create table T(ID int primary key, c int); 如果要 ...
- 当程序执行一条查询语句时,MySQL内部到底发生了什么? (说一下 MySQL 执行一条查询语句的内部执行过程?
先来个最基本的总结阐述,希望各位小伙伴认真的读一下,哈哈: 1)客户端(运行程序)先通过连接器连接到MySql服务器. 2)连接器通过数据库权限身份验证后,会先查询数据库缓存是否存在(之前执行过相同条 ...
- MySQL:一条更新语句是如何执行的
目录 引言 更新流程图 更新流程说明 第一步:更新数据 数据页内存 Change Buffer 第二步:缓存日志内容 redo log buffer binlog cache 第三步:日志写入磁盘 两 ...
- 一条查询SQl是怎样执行的
MySQL的逻辑架构图 大体来说,MySQL可以分为Server层和存储引擎层两部分. Server层包括连接器.查询缓存.分析器,优化器等,涵盖MySQL的大多核心服务功能,以及所有的内置函数,存储 ...
- MySQL概述 - 一条查询sql语句的执行过程
Server层 连接器 建立连接.获取权限.维持和管理连接. 连接建立比较复杂,建议使用长连接 定期断开长连接 mysql_reset_connection指令 查询缓存 建议关闭,任何更新操作会此t ...
- MySQL:一条SQL是如何执行的
目录 MySQL基本架构 Server层 连接器 查询缓存 分析器 优化器 执行器 存储引擎层 InnoDB MyISAM Memory SQL执行流程 MySQL基本架构 在讲SQL语句是如何执行之 ...
- MySql 学习之 一条查询sql的执行过程
相信大家都接触过Mysql数据库,而且也肯定都会写sql.我不知道大家有没有这样的感受,反正我是有过这样的想法.就是当我把一条sql语句写完了,并且执行完得到想要的结果.这时我就在想为什么我写这样的一 ...
随机推荐
- poj_1852_Ants(复杂问题简单化)
原题传送门 描述 一群蚂蚁走在长度为l cm的水平细杆上,以1cm/s的匀速.当一只行走的蚂蚁到达杆的一端,它就会掉下去.当两只蚂蚁相遇,它们会掉头像反方向走去.我们知道一只蚂蚁在杆上的初始位置,然而 ...
- 你不需要基于 CSS Grid 的栅格布局系统
在过去的几个星期里,我开始看到基于 CSS Grid 的布局框架和栅格系统的出现.我们惊讶它为什么出现的这么晚.但除了使用 CSS Grid 栅格化布局,我至今还没有看到任何框架能提供其他有价值的东西 ...
- H5进阶篇--实现微信摇一摇功能
在HTML5中,DeviceOrientation特性所提供的DeviceMotion事件封装了设备的运动传感器时间,通过改时间可以获取设备的运动状态.加速度等数据(另还有deviceOrientat ...
- Java/C++实现模板方法模式---数据库操作
对数据库的操作一般包括连接.打开.使用.关闭等步骤,在数据库操作模板类中我们定义了connDB().openDB().useDB().closeDB()四个方法分别对应这四个步骤.对于不同类型的数据库 ...
- c++实现中介者模式--虚拟聊天室
内容: 在"虚拟聊天室"实例中增加一个新的具体聊天室类和一个新的具体会员类,要求如下: 1. 新的具体聊天室中发送的图片大小不得超过20M. 2. 新的具体聊天室中发送的文字长度不 ...
- [ Skill ] map mapc mapcan mapcar mapcon maplist mapinto
https://www.cnblogs.com/yeungchie/ 几种 map 函数的差异 map map( lambda(( a b ) println( list( a b )) ) list ...
- python的编译和解释
编译和解释 1.编译: 将源代码一次性转换成目标代码的过程 源代码 → 编辑器 →目标代码 →程序执行(同时程序输入)→结果输出 2.解释: 将源代码逐条转换成目标代码同时逐条运行的过程 源代码+程序 ...
- mysql server_id的用途(主从等结构中)
前言 我们都知道MySQL用server-id来唯一的标识某个数据库实例,并在链式或双主复制结构中用它来避免sql语句的无限循环.5.7需要同时设置server_id参数,8.0开始server_id ...
- 另类终端「GitHub 热点速览 v.22.15」
作者:HelloGitHub-小鱼干 除了编译器之外,终端也是我们日常打交道的软件之一.但,你用它看过股票吗?OpenBBTerminal 不仅能让你看股票,还能让你用科学的方法进行股票投资.说到投资 ...
- Centos7 搭建 Socks 服务
Centos7 搭建 Socks 服务 一丶拿到一个动态拨号的服务器还不能使用网络得先打开: pppoe-start 二丶安装命令汇总: 通过yum安装ss5 依赖包: yum install gcc ...