【MYSQL】如何解决 bin log 与 redo log 的一致性问题

该问题问的其实就是redo log 的两阶段提交

为什么说redo log 具有崩溃恢复的能力

MySQL Server 层拥有的 bin log 只能用于归档,不足以实现崩溃恢复(crash-safe),需要借助 InnoDB 引擎的 redo log 才能拥有崩溃恢复的能力。所谓崩溃恢复就是:即使在数据库宕机的情况下,也不会出现操作一半的情况

至于为什么说 redo log 具有崩溃恢复的能力,而 bin log 没有,我们先来简单看一下这两种日志有哪些不同点:

1)适用对象不同:

bin log 是 MySQL 的 Server 层实现的,所有引擎都可以使用
而 redo log 是 InnoDB 引擎特有的

2)写入内容不同:

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

3)写入方式不同:

bin log 是可以追加写入的。“追加写” 是指 bin log 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志
redo log 是循环写的,空间固定会被用完
可以看到,redo log 和 bin log 的一个很大的区别就是,一个是循环写,一个是追加写。也就是说 redo log 只会记录未刷入磁盘的日志,已经刷入磁盘的数据都会从 redo log 这个有限大小的日志文件里删除。

而 bin log 是追加日志,保存的是全量的日志。这就会导致一个问题,那就是没有标志能让 InnoDB 从 bin log 中判断哪些数据已经刷入磁盘了,哪些数据还没有。

举个例子,bin log 记录了两条日志:

记录 1:给 id = 1 这一行的 age 字段加 1
记录 2:给 id = 1 这一行的 age 字段加 1

假设在记录 1 刷盘后,记录 2 未刷盘时,数据库崩溃。重启后,只通过 bin log 数据库是无法判断这两条记录哪条已经写入磁盘,哪条没有写入磁盘,不管是两条都恢复至内存,还是都不恢复,对 id = 1 这行数据来说,都是不对的。

但 redo log 不一样,只要刷入磁盘的数据,都会从 redo log 中被抹掉,数据库重启后,直接把 redo log 中的数据都恢复至内存就可以了。

这就是为什么说 redo log 具有崩溃恢复的能力,而 bin log 不具备。

redo log 两阶段提交

查询语句

前面我们介绍过一条 SQL 查询语句的执行过程,简单回顾:

1、MySQL 客户端与服务器间建立连接,客户端发送一条查询给服务器;

2、服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果;否则进入下一阶段;

3、服务器端进行 SQL 解析、预处理,生成合法的解析树;

4、再由优化器生成对应的执行计划;

5、执行器根据优化器生成的执行计划,调用相应的存储引擎的 API 来执行,并将执行结果返回给客户端

在这里插入图片描述

更新语句

对于更新语句来说,这套流程同样也是要走一遍的,不同的是,更新流程还涉及两个重要的日志模块 bin log 和 redo log。

以下面这条简单的 SQL 语句为例,我们来解释下执行器和 InnoDB 存储引擎在更新时做了哪些事情:

update table set age = age + 1 where id = 1;

1、执行器:找存储引擎取到 id = 1 这一行记录

2、存储引擎:根据主键索引树找到这一行,如果 id = 1 这一行所在的数据页本来就在内存池(Buffer Pool)中,就直接返回给执行器;否则,需要先从磁盘读入内存池,然后再返回

3、执行器:拿到存储引擎返回的行记录,把 age 字段加上 1,得到一行新的记录,然后再调用存储引擎的接口写入这行新记录

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

5、执行器:生成这个操作的 bin log,并把 bin log 写入磁盘

6、执行器:调用存储引擎的提交事务接口

7、存储引擎:把刚刚写入的 redo log 状态改成提交(commit)状态,更新完成

在这里插入图片描述
可以看到,所谓两阶段提交,其实就是把 redo log 的写入拆分成了两个步骤:prepare 和 commit。

所以,为什么要这样设计呢?这样设计怎么就能够实现崩溃恢复呢?

根据两阶段提交,崩溃恢复时的判断规则是这样的:
1、如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交
2、如果 redo log 里面的事务处于 prepare 状态,则判断对应的事务 binlog 是否存在并完整
a. 如果 binlog 存在并完整,则提交事务;
b. 否则,回滚事务。

注: MySQL 咋知道 bin log 是不是完整的?
简单来说,一个事务的 binlog 是有完整格式的:
1、statement格式的 bin log,最后会有 COMMIT
2、row 格式的 bin log,最后会有 XID event

实际的例子

1、假设数据库在写入 redo log(prepare) 阶段之后、写入 binlog 之前,发生了崩溃,此时 redo log 里面的事务处于 prepare 状态,binlog 还没写,所以崩溃的时候,这个事务会回滚。

由于 binlog 还没写,所以也就不会传到备库,从而避免主备不一致的情况

在这里插入图片描述

2、如果数据库在写入 binlog 之后,redo log 状态修改为 commit 前发生崩溃,此时 redo log 里面的事务仍然是 prepare 状态,binlog 存在并完整,所以即使在这个时刻数据库崩溃了,事务仍然会被正常提交。

因为 binlog 已经写入成功了,这样之后就会被从库同步过去,但是实际上主库并没有完成这个操作,所以为了主备一致,在主库上需要提交这个事务。

在这里插入图片描述
其实可以看出来,处于 prepare 阶段的 redo log 加上完整的 bin log,就能保证数据库的崩溃恢复了。

如果数据库在写入 binlog 之前,此时 redo log 里面的事务是 prepare 状态,binlog 存在但不完整,在这个时刻数据库崩溃了,事务就会被回滚。

redo log两阶段提交的重要性(可不可以先 redo log 写完,再写 bin log 或者反过来?)

1)对于先写完 redo log 后写 bin log 的情况:

假设在 redo log 写完,bin log 还没有写完的时候,MySQL 崩溃。主库中的数据确实已经被修改了,但是这时候 bin log 里面并没有记录这个语句。因此,从库同步的时候,就会丢失这个更新,和主库不一致。

在这里插入图片描述

2)对于先写完 binlog 后写 redo log 的情况
如果在 bin log 写完,redo log 还没写的时候,MySQL 崩溃。因为 binlog 已经写入成功了,这样之后就会被从库同步过去,但是实际上 redo log 还没写,主库并没有完成这个操作,所以从库相比主库就会多执行一个事务,导致主备不一致

在这里插入图片描述

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

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

相关文章

二刷力扣——单调栈

739. 每日温度 单调栈应该从栈底到栈顶 是递减的。 找下一个更大的 ,用递减单调栈,就可以确定在栈里面的每个比当前元素i小的元素,下一个更大的就是这个i,然后弹出并记录;然后当前元素i入栈,仍然满足递减…

Java进阶----继承

继承 一.继承概述 继承是可以通过定义新的类,在已有类的基础上扩展属性和功能的一种技术. 案例:优化 猫、狗JavaBean类的设计 狗类:Dog 属性:名字 name,年龄 age 方法:看家 watchHome(),Gett…

Android多开应用软件系统设计

设计一个支持Android多开应用的软件系统,主要涉及到以下几个关键技术点和设计考虑: 1. 虚拟化技术 容器技术:与传统的虚拟机不同,可以采用更轻量级的容器技术,为每个应用实例创建独立的运行环境。这包括分配独立的用…

HTTP 请求走私漏洞详解

超详细的HTTP请求走私漏洞教程,看完还不会你来找我。 1. 简介 HTTP请求走私漏洞(HTTP Request Smuggling)发生在前端服务器(也称代理服务器,一般会进行身份验证或访问控制)和后端服务器在解析HTTP请求时&…

上位机图像处理和嵌入式模块部署(mcu项目2:串口日志记录器)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 淘宝上面有一个商品蛮好玩的,那就是日志记录器。说是记录器,其实就是一个模块,这个模块的输入是一个ttl串口&am…

利用Python进行数据分析PDF下载经典数据分享推荐

本书由Python pandas项目创始人Wes McKinney亲笔撰写,详细介绍利用Python进行操作、处理、清洗和规整数据等方面的具体细节和基本要点。第2版针对Python 3.6进行全面修订和更新,涵盖新版的pandas、NumPy、IPython和Jupyter,并增加大量实际案例…

Docker Desktop如何换镜像源?

docker现在很多镜像源都出现了问题,导致无法拉取镜像,所以找到一个好的镜像源,尤为重要。 一、阿里镜像源 经过测试,目前,阿里云镜像加速地址还可以使用。如果没有阿里云账号,需要先注册一个账号。 地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 二…

基于Java技术的B/S模式书籍学习平台

你好,我是专注于计算机科学领域的学姐码农小野。如果你对书籍学习平台开发感兴趣或有相关需求,欢迎私信联系我。 开发语言: Java 数据库: MySQL 技术: B/S模式、Java技术 工具: Eclipse、Navicat、Mave…

【Go】函数的使用

目录 函数返回多个值 init函数和import init函数 main函数 函数的参数 值传递 引用传递(指针) 函数返回多个值 用法如下: package mainimport ("fmt""strconv" )// 返回多个返回值,无参数名 func Mu…

ctfshow web入门 nodejs web334--web337

web334 有个文件下载之后改后缀为zip加压就可以得到两个文件 一个文件类似于index.php 还有一个就是登录密码登录成功就有flag username:ctfshow password:123456因为 return name!CTFSHOW && item.username name.toUpperCase() && item.password passwor…

SpringBoot的热部署和日志体系

SpringBoot的热部署 每次修改完代码,想看效果的话,不用每次都重新启动代码,等待项目重启 这样就可以了 JDK官方提出的日志框架:Jul log4j的使用方式: (1)引入maven依赖 (2&#x…

OS Copilot测评-CSDN

登录控制台 安装插件 sudo yum install -y os-copilot效果如下 配置 AccessKey ID 与 AccessKey Secret 注意安全,使用完成后,别忘了去控制台删除,一般情况使用子Key就可以 检测是否可用 co hi实际操作(当前为官方案例请求) 实操1&…

RoPE 旋转位置编码,详细解释(下)NLP 面试的女生彻底说明白了

RoPE 旋转位置编码,详细解释(下)NLP 面试的女生彻底说明白了 原创 看图学 看图学 2024年07月01日 07:55 北京 书接上文,上文见:这么解释 RoPE 旋转位置编码,女朋友睁大了双眼(上) …

metersphere链接腾讯邮箱步骤

1、打开腾讯邮箱生成授权码 路径:设置-账户-账户安全 生成的授权码只会展示1次,注意保存 2、在系统设置-系统参数设置-邮件设置填写授权码和SMTP信息 SMTP信息在邮箱的客户端设置中可以获取到对应的信息 3、信息填写完后,可以测试连接&…

集成sa-token前后端分离部署配置corsFliter解决跨域失效的真正原因

文章目录 1.前言2.问题复现3.解决方法3.1 方式一:后端修改CorsFilter源码3.2 方式二:前端禁用或移除浏览器referrer-policy引用者策略 4.总结 1.前言 缘由请参看下面这篇文章:sa-token前后端分离解决跨域的正确姿势 https://mp.weixin.qq.co…

桌面记笔记的软件:能加密的笔记app

在日常生活和工作中,很多人都有记笔记的习惯。无论是记录会议要点、学习心得,还是生活中的点滴灵感,笔记都是我们不可或缺的好帮手。然而,传统的纸笔记录方式逐渐不能满足现代人的需求,因为纸质笔记不易保存、查找困难…

STM32 - SPI硬件外设

配合我的上一篇SPI ​​​​​​通信 协议-CSDN博客一起理解更佳,本文后看 SPI 是由摩托罗拉(Motorola)公司开发的全双工同步串行总线,是 MCU 和外围设备之间进行通信的同步串行端口。主要应用在EEPROM、Flash、RTC、ADC、网络控制器、MCU、DSP以及数字信…

网上怎么样可以挣钱,分享几种可以让你在家赚钱的兼职项目

当今社会,压力越来越大,工作、家庭、生活等等,方方面面都需要钱,仅靠一份工作赚钱,已经很难满足我们的需求。所以很多人都会尝试做一些副业,兼职来补贴家用。 现在呢,有很多人都想在网上赚钱&am…

微型导轨如何提升数控机床的稳定性?

数控机床是加工设备中常用的机床,精度和稳定性是衡量数控机床性能的重要指标。而微型导轨作为数控机床中重要的传动元件,数控机床与其具体结构性能是密不可分的,那么微型导轨如何提高数控机床的稳定性呢? 1、微型导轨通过采用先进…

githup开了代理push不上去

你们好,我是金金金。 场景 git push出错 解决 cmd查看 git config --global http.proxy git config --global https.proxy 如果什么都没有,代表没设置全局代理,此时如果你开了代理,则执行如下,设置代理 git con…