【MySQL实战45讲笔记】基础篇——redo log 和 binlog

系列文章

基础篇——MySQL 的基础架构


目录

  • 系列文章
  • 1. 重要的日志模块:redo log 和 binlog
    • 1.1 redo log
    • 1.2 binlog
    • 1.3 执行器和 InnoDB 引擎内部如何执行更新语句


1. 重要的日志模块:redo log 和 binlog

前面系统的了解了一个查询语句的执行流程,一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。对于一条更新语句,还是会同样经历一遍这个过程,与查询流程不一样的是,更新流程还涉及两个重要的日志模块:redo log(重做日志)和 binlog(归档日志)。

mysql> update T set c=c+1 where ID=2;

1.1 redo log

《孔乙己》这篇文章,酒店掌柜有一个粉板,专门用来记录客人的赊账记录。如果赊账的人不多,那么他可以把顾客名和账目写在板上。但如果赊账的人多了,粉板总会有记不下的时候,这个时候掌柜一定还有一个专门记录赊账的账本。如果有人要赊账或者还账的话,掌柜一般有两种做法:一种做法是直接把账本翻出来,把这次赊的账加上去或者扣除掉;另一种做法是先在粉板上记下这次的账,等打烊以后再把账本翻出来核算。在生意红火柜台很忙时,掌柜一定会选择后者,因为前者操作实在是太麻烦了。首先,你得找到这个人的赊账总额那条记录。你想想,密密麻麻几十页,掌柜要找到那个名字,可能还得带上老花镜慢慢找,找到之后再拿出算盘计算,最后再将结果写回到账本上。

而粉板和账本配合的整个过程,其实就是 MySQL 里经常说到的 WAL 技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘,也就是先写粉板,等不忙的时候再写账本。

具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(粉板)里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做,这就像打烊以后掌柜做的事。

以上就是为什么需要日志,原因之一是写磁盘是随机写,效率低,写日志是顺序写,并且还可以组提交,磁盘压力相对小。

redo log就相当于“粉板”,它 是InnoDB引擎独有的,是存储引擎层的,是物理日志。并且是循环写,配合checkpoint来保证即使数据库发生异常重启,之前提交的记录都不会丢失,即crash-safe

InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB(innodb_log_file_size 设置大小和 innodb_log_files_in_group 设置个数),那么这块“粉板”总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示:

img

  • write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
  • write pos 和 checkpoint 之间的是“粉板”上还空着的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。

1.2 binlog

上面我们聊到的“粉板” redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志)。

binlog是Server层的,是逻辑日志,并且是追加写的,意思是binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志(就像是“账本”)。

会有两份日志的原因:

  • 一个是历史原因,最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog 日志只能用于归档。而 InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统——也就是 redo log 来实现 crash-safe 能力
  • 另一个是操作原因:binlog是可以关的,你如果有权限,可以set sql_log_bin=0关掉本线程的binlog日志。 所以只依赖binlog来恢复就靠不住

redo log 和 binlog 主要有三个区别:

  1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。

  2. redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。

    • 关于逻辑日志和物理日志的区别:

      物理日志存储数据库中特定记录的变更,通常是 page oriented,即描述具体某一个 page 的修改操作。比如一条更新请求对应的初始值(original value)以及更新值(after value); 逻辑日志存储事务中的一个操作。比如事务中的 UPDATE、DELETE 以及 INSERT 操作。

      逻辑日志更抽象,其不需要指明更新操作具体作用于哪一块 page,因此也对底层少了一些限制。如果利用物理日志进行宕机后的数据恢复,那么需要确保 page 不能够改变,但利用逻辑日志并不在乎底层 page 是否改变。
      MySQL中逻辑日志的本质就是对更新语句(update query)本身的落盘,只需要指明在哪一张表上的哪一行,对哪一些字段进行什么修改即可。逻辑日志不用物理上的 page,而用逻辑上的表。
      所以一个逻辑日志可以对应多条物理日志。

  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

1.3 执行器和 InnoDB 引擎内部如何执行更新语句

mysql> update T set c=c+1 where ID=2;
  1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。

  2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。

  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。

  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。

  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

img

这里redo log 的写入被拆成了两个步骤:preparecommit,这就是"两阶段提交"。

要有两阶段提交的原因是保障数据一致性。如果不使用“两阶段提交”,那么原数据库的状态就有可能和用binlog 恢复出来的库的状态不一致。

所以简单来说两阶段提交就是: 1. redo log prepare –> 2. binlog –> 3. redo log commit

  • 就是以binlog为基准,有binlog就算作已经提交,没有binlog就算作没有提交
  • 如果在2步骤之前系统崩溃,当重启回复后,发现没有commit就会回滚,如果使用备份恢复,因为binlog还没有记录,所以两个数据库数据一致
  • 如果在3步骤之前系统崩溃,当重启回复后,发现虽然没有commit,但满足prepare和binlog完整,所以重启后会自动commit,所以可以通过redo log恢复数据,如果使用备份恢复,因为binlog已经成功记录,所以两个数据库数据也一致。
  • 所以事务正常执行是要commit 才算完,但是崩溃恢复过程的话,可以接受“redolog prepare 并且binlog完整” 的情况,因为这种情况可以达到“用binlog恢复的库跟原库逻辑相同” 这个要求。

最后是本篇的思维导图作为参考:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/919378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB常见数学运算函数

MATLAB中含有许多有用的函数,可以随时调用。 a b s abs abs函数 a b s abs abs函数在MATLAB中可以求绝对值,也可以求复数的模长:c e i l ceil ceil函数 向正无穷四舍五入(如果有小数,就向正方向进一)f l o o r floor floor函数 向负无穷四舍五入(如果有小数,就向负方向…

MySQL无开通SQL全审计下的故障分析方法

几年前MySQL数据库出现突然的从库延迟故障和CPU爆高时,如何排查具体原因,可能说已在腾讯云的MySQL库里开启了SQL全审计,记录了全部执行的SQL,再通过下面的方法就可以很容易找到原因: 1,实用QPS和TPS高的高效…

新手教学系列——善用 VSCode 工作区,让开发更高效

引言 作为一名开发者,你是否曾经在项目中频繁地切换不同文件夹,打开无数个 VSCode 窗口?特别是当你同时参与多个项目或者处理多个模块时,这种情况更是家常便饭。很快,你的任务栏上挤满了 VSCode 的小图标,切换起来手忙脚乱,工作效率直线下降。这时候,你可能会问:“有…

React(一)

文章目录 项目地址一、创建第一个react项目二、JSX语法2.1 生成列表2.2 大括号识别JS的表达式2.3 列表循环array2.4 条件判断以及假值显示2.5 复杂条件渲染2.6 事件监听和绑定2.7 使用Fregments返回多个根标签2.8 多条件渲染2.9 导出子组件 三、组件3.1 设置组件3.2 props给子组…

微服务安全Spring Security Oauth2实战_spring-security-oauth2-authorization-server

Spring Authorization Server 是什么 Spring Authorization Server 是一个框架,它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。它建立在 Spring Security 之上,为构建 OpenID Connect 1.0 身份提供者和 OAuth2 授权服务器产品…

多线程-02-多线程的典型应用(异步调用和提高效率)

一、怎么理解异步和同步 从方法的角度去理解: 需要等待结果返回,才能继续运行就是同步不需要等待结果返回,就能继续运行就是异步 注意:同步在多线程中还有另外一层意思:是让多个线程步调一致。 同步调用 同步调用…

【数据分享】中国汽车工业年鉴(1986-2023)

本年鉴是由工业和信息化部指导,中国汽车技术研究中心有限公司与中国汽车工业协会联合主办。《年鉴》是全面、客观记载中国汽车工业发展与改革历程的重要文献,内容涵盖汽车产业政策、标准、企业、市场以及全国各省市汽车工业发展情况,并调查汇…

Matlab实现北方苍鹰优化算法优化随机森林算法模型 (NGO-RF)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 北方苍鹰优化算法(Northern Goshawk Optimization, NGO)是一种新颖的群智能优化算法,灵感源自北方苍鹰捕食时的策略。该算法通过模拟苍鹰的搜寻、接近和捕捉猎物的行为模式&am…

CentOS使用中遇到的问题及解决方法

一、CentOS 7网络配置(安装后无法联网问题) 现象说明 在安装CentOS系统后,有可能出现无法联网的问题,虚拟机中的网络配置并没有问题,而系统却无法联网,也ping不通。 原因描述 CentOS默认开机不启动网络,因…

QT基础 UI编辑器 QT5.12.3环境 C++环境

一、UI编辑器 注意:创建工程时,要勾上界面按钮 UI设计师界面的模块 UI编辑器会在项目构建目录中自动生成一个ui_xxx.h(构建一次才能生成代码),来表示ui编辑器界面的代码,属于自动生成的,一定不…

数据分析-Excel基础操作

目录 周报讲解 基础概念 理解数据 筛选excel表 数据透视表 插入数据透视表 新建字段 切片器(筛选) 数据透视图 Excel常用函数 sum(求和) 1-8月GMV 1月和8月GMV sumif(条件求和) sumifs 日G…

OpenCV双目立体视觉重建

本篇文章主要给出使用opencv sgbm重建三维点云的代码,鉴于自身水平所限,如有错误,欢迎批评指正。 环境:vs2015 ,opencv3.4.6,pcl1.8.0 原始数据使用D455采集,图像已做完立体校正,如下…

Clip结合Faiss+Flask简易版文搜图服务

一、实现 使用目录结构&#xff1a; templates ---upload.html faiss_app.py 前端代码&#xff1a;upload.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content&quo…

Linux驱动开发快速入门——字符设备驱动(直接操作寄存器设备树版)

Linux驱动开发快速入门——字符设备驱动 前言 笔者使用开发板型号&#xff1a;正点原子的IMX6ULL-alpha开发板。ubuntu版本为&#xff1a;20.04。写此文也是以备忘为目的。 字符设备驱动 本小结将以直接操作寄存器的方式控制一个LED灯&#xff0c;可以通过read系统调用可以…

概念解读|K8s/容器云/裸金属/云原生...这些都有什么区别?

随着容器技术的日渐成熟&#xff0c;不少企业用户都对应用系统开展了容器化改造。而在容器基础架构层面&#xff0c;很多运维人员都更熟悉虚拟化环境&#xff0c;对“容器圈”的各种概念容易混淆&#xff1a;容器就是 Kubernetes 吗&#xff1f;容器云又是什么&#xff1f;容器…

《机器人控制器设计与编程》考试试卷**********大学2024~2025学年第(1)学期

消除误解&#xff0c;课程资料逐步公开。 复习资料&#xff1a; Arduino-ESP32机器人控制器设计练习题汇总_arduino编程语言 题-CSDN博客 试卷样卷&#xff1a; 开卷考试&#xff0c;时间&#xff1a; 2024年11月16日 001 002 003 004 005 ……………………装………………………

本地音乐服务器(三)

6. 删除音乐模块设计 6.1 删除单个音乐 1. 请求响应设计 2. 开始实现 首先在musicmapper新增操作 Music findMusicById(int id);int deleteMusicById(int musicId); 其次新增相对应的.xml代码&#xff1a; <select id"findMusicById" resultType"com.exa…

如何在项目中用elementui实现分页器功能

1.在结构部分复制官网代码&#xff1a; <template> 标签: 这是 Vue 模板的根标签&#xff0c;包含所有的 HTML 元素和 Vue 组件。 <div> 标签: 这是一个普通的 HTML 元素&#xff0c;包裹了 el-pagination 组件。它没有特别的意义&#xff0c;只是为了确保 el-pagi…

VB.Net笔记-更新ing

1.1 设置默认VS的开发环境为VB.NET&#xff08;2024/11/18&#xff09; 1.2 新建一个“Hello&#xff0c;world”的窗体&#xff08;2024/11/18&#xff09; 1.3 计算圆面积的小程序&#xff08;2024/11/18&#xff09; 显示/隐式 声明 &#xff08;2024/11/18&#xff0…

每日一练:【优先算法】双指针之移动零(easy)

双指针概念介绍 常见的双指针有两种形式&#xff0c;一种是对撞指针&#xff0c;一种是左右指针。 对撞指针&#xff1a;一般用于顺序结构中&#xff0c;也称左右指针。 • 对撞指针从两端向中间移动。一个指针从最左端开始&#xff0c;另一个从最右端开始&#xff0c;然后逐渐…