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

news2024/11/21 0:11:24

系列文章

基础篇——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恢复的库跟原库逻辑相同” 这个要求。

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Redis】Redis实现的消息队列

一、用list实现【这是数据类型所以支持持久化】 消息基于redis存储不会因为受jvm内存上限的限制,支持消息的有序性,基于redis的持久化机制,只支持单一消费者订阅,无法避免消息丢失。 二、用PubSub【这不是数据类型,是…

(计算机毕设)基于SpringBoot+Vue的房屋租赁系统的设计与实现

博主可接毕设设计!!! 各种毕业设计源码只要是你有的题目我这里都有源码 摘 要 社会的发展和科学技术的进步,互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。互…

云原生之运维监控实践-使用Prometheus与Grafana实现对Nginx和Nacos服务的监测

背景 如果你要为应用程序构建规范或用户故事,那么务必先把应用程序每个组件的监控指标考虑进来,千万不要等到项目结束或部署之前再做这件事情。——《Prometheus监控实战》 去年写了一篇在Docker环境下部署若依微服务ruoyi-cloud项目的文章,当…

游戏引擎学习第19天

介绍 这段内容描述了开发者在进行游戏开发时,对于音频同步和平台层的理解和调整的过程。以下是更详细的复述: 开发者表达了他希望今天继续进行的工作内容。他提到,昨天他讲解了一些关于音频的内容,今天他想稍微深入讲解一下他正…

node版本升级,从卸载到使用nvm管理node版本并配置vue环境(学习趟雷版)

查找node版本和安装路径 查找当前node版本 node -v 查看弄得版本安装路径 where node 卸载node(没安装过node的可以直接跳过) 通过控制面板删除node,按下【winR】键,输入control 控制面板找到默认程序 找到node程序点击卸载 …

每天五分钟机器学习:支持向量机算法数学基础之核函数

本文重点 从现在开始,我们将开启支持向量机算法的学习,不过在学习支持向量机算法之前,我们先来学习一些支持向量机所依赖的数学知识,这会帮助我们更加深刻的理解支持向量机算法,本文我们先来学习核函数。 定义 核函数(Kernel Function)是一种在支持向量机(SVM)、高…

机器学习基础04

目录 1.朴素贝叶斯-分类 1.1贝叶斯分类理论 1.2条件概率 1.3全概率公式 1.4贝叶斯推断 1.5朴素贝叶斯推断 1.6拉普拉斯平滑系数 1.7API 2.决策树-分类 2.1决策树 2.2基于信息增益的决策树建立 2.2.1信息熵 2.2.2信息增益 2.2.3信息增益决策树建立步骤 2.3基于基…

STM32芯片EXIT外部中断的配置与原理以及模板代码(标准库)

配置EXIT外部中断其实就是把GPIO刀NVIC的各个外设配置好 第一步:配置RCC,把我们涉及到的外设的时钟都打开 (此处EXTI是默认打开的,而NVIC是内核外设无需配置) 第二步:配置GPIO,选择端口为输入模式 第三…

pytest结合allure做接口自动化

这是一个采用pytest框架,结合allure完成接口自动化测试的项目,最后采用allure生成直观美观的测试报告,由于添加了allure的特性,使得测试报告覆盖的内容更全面和阅读起来更方便。 1. 使用pytest构建测试框架,首先配置好…

生成自签名证书并配置 HTTPS 使用自签名证书

生成自签名证书 1. 运行 OpenSSL 命令生成证书和私钥 在终端中输入以下命令,生成自签名证书和私钥文件: sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout self_signed.key -out self_signed.pem-x509:生成自签名证书。…

Linux网络:守护进程

Linux网络:守护进程 会话进程组会话终端 守护进程setsiddaemon 在创建一个网络服务后,往往这个服务进程是一直运行的。但是对于大部分进程来说,如果退出终端,这个终端上创建的所有进程都会退出,这就导致进程的生命周期…

5.4.2-1 编写Java程序在HDFS上创建文件

本次实战涉及使用Java操作Hadoop HDFS,包括创建文件、判断文件存在性及异常处理。通过手动添加依赖、启动HDFS服务,成功在HDFS上创建和检查文件。进一步探索了文件操作的最佳实践,如检查文件存在性以避免重复创建,以及处理HDFS安全…

十六.SpringCloudAlibaba极简入门-整合Grpc代替OpenFeign

前言 他来了他来了,停了快2个月了终于又开始更新文章啦,这次带来的绝对是干货!!!。由于公司项目进行重构的时候考虑到,OpenFeign做为服务通信组件在高并发情况下有一定的性能瓶颈,所以将其替换…

【pytest】pytest注解使用指南

前言:在 pytest 测试框架中,注解(通常称为装饰器)用于为测试函数、类或方法提供额外的信息或元数据。这些装饰器可以影响测试的执行方式、报告方式以及测试的组织结构。pytest 提供了多种内置的装饰器,以及通过插件扩展…

百度AI人脸检测与对比

1.注册账号 打开网站 https://ai.baidu.com/ &#xff0c;注册百度账号并登录 2.创建应用 3.技术文档 https://ai.baidu.com/ai-doc/FACE/yk37c1u4t 4.Spring Boot简单集成测试 pom.xml 配置&#xff1a; <!--百度AI--> <dependency> <groupId>com.baidu.…

A040-基于springboot的智能停车计费系统设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

力扣 LeetCode 222. 完全二叉树的节点个数(Day7:二叉树)

解题思路&#xff1a; 解法一&#xff1a;普通二叉树解法 使用后序遍历 有一行的精简版代码但不利于理解采用的哪一种遍历方式 解法二&#xff1a;利用上完全二叉树的特点 一个指针left&#xff0c;一个指针right left一直向左遍历&#xff0c;right一直向右遍历&#xff…

hhdb数据库介绍(9-21)

计算节点参数说明 checkClusterBeforeDnSwitch 参数说明&#xff1a; PropertyValue参数值checkClusterBeforeDnSwitch是否可见否参数说明集群模式下触发数据节点高可用切换时&#xff0c;是否先判断集群所有成员正常再进行数据节点切换默认值falseReload是否生效是 参数设…

百度智能云千帆大模型平台引领企业创新增长

本文整理自百度世界大会 2024——「智能跃迁 产业加速」论坛的同名演讲。 更多大会演讲内容&#xff0c;请访问&#xff1a; https://baiduworld.baidu.com 首先&#xff0c;跟大家分享一张图&#xff0c;这个是我们目前大模型应用落地的场景分布。可以看到&#xff0c;大模型…

得物彩虹桥架构演进之路-负载均衡篇

文 / 新一 一、前言 一年一更的彩虹桥系列又来了&#xff0c;在前面两期我们分享了在稳定性和性能2个层面的一些演进&优化思路。近期我们针对彩虹桥 Proxy 负载均衡层面的架构做了一次升级&#xff0c;目前新架构已经部署完成&#xff0c;生产环境正在逐步升级中&#xf…