【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.rhkb.cn/news/375470.html

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

相关文章

Java毕业设计 基于SSM vue电影订票系统小程序 微信小程序

Java毕业设计 基于SSM vue电影订票系统小程序 微信小程序 SSM 电影订票系统小程序 功能介绍 用户 登录 注册 忘记密码 首页 图片轮播 电影信息 电影详情 评论 收藏 预订 电影资讯 资讯详情 用户信息修改 电影评价 我的收藏管理 用户充值 在线客服 我的订单 管理员 登录 个人…

sqlite 数据库 介绍

文章目录 前言一、什么是 SQLite ?二、语法三、SQLite 场景四、磁盘文件 前言 下载 目前已经出到了, Version 3.46.0 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是…

STM32-OC输出比较和PWM

本内容基于江协科技STM32视频内容,整理而得。 文章目录 1. OC输出比较和PWM1.1 OC输出比较1.2 PWM(脉冲宽度调制)1.3 输出比较通道(高级)1.4 输出比较通道(通用)1.5 输出比较模式1.6 PWM基本结…

批量制作word表格

问题背景 将excel表中的成绩内容制作为成绩单,每页对应一个学员的成绩,方便打印 代码实现 ## 导入包 import pandas as pd from docx import Document from docx.enum.text import WD_ALIGN_PARAGRAPH,WD_LINE_SPACING# 读取 Excel 内容 df pd.read_e…

docker基础知识以及windows上的docker desktop 安装

记录以供备忘 基础概念: 什么是docker 将程序和环境一起打包,以在不同操作系统上运行的工具软件 什么是基础镜像 选一个基础操作系统和语言后,将对应的文件系统、依赖库、配置等打包为一个类似压缩包的文件,就是基础镜像 什么是…

基于FPGA的数字信号处理(15)--定点数的舍入模式(6)向0取整fix

前言 在之前的文章介绍了定点数为什么需要舍入和几种常见的舍入模式。今天我们再来看看另外一种舍入模式:向上取整fix。 10进制数的fix fix:也叫 向0取整。它的舍入方式是数据往0的方向,舍入到最近的整数,比如1.75 fix到2&#xf…

【SQL】如何用SQL写透视表

【背景】 报表中有一大需求是透视表,目前有很多分析类应用也搭载了此类功能,那么我们能不能直接用SQL做透视表呢? 【分析】 BI类软件将透视表功能做在了前端,但是数据本身还是存储在数据库中,所以必然有方法可以用SQL直接实现透视表。 【心法】 透视表是任意选取一个…

LVS集群及其它的NAT模式

1.lvs集群作用:是linux的内核层面实现负载均衡的软件;将多个后端服务器组成一个高可用、高性能的服务器的集群,通过负载均衡的算法将客户端的请求分发到后端的服务器上,通过这种方式实现高可用和负载均衡。 2.集群和分布式&#…

开源项目的认识理解

目录 开源项目有哪些机遇与挑战? 1.开源项目的发展趋势 2.开源的经验分享(向大佬请教与上网查询) 3.开源项目的挑战 开源项目有哪些机遇与挑战? 1.开源项目的发展趋势 1. 持续增长与普及 - 开源项目将继续增长&#xff0c…

Java客户端调用SOAP方式的WebService服务实现方式分析

简介 在多系统交互中,有时候需要以Java作为客户端来调用SOAP方式的WebService服务,本文通过分析不同的调用方式,以Demo的形式,帮助读者在生产实践中选择合适的调用方式。 本文JDK环境为JDK17。 结论 推荐使用Axis2或者Jaxws&#…

3款自己电脑就可以运行AI LLM的项目

AnythingLLM、LocalGPT和PrivateGPT都是与大语言模型(LLM)相关的项目,它们允许用户在本地环境中与文档进行交互,但它们在实现方式和特点上存在一些差异。AnythingLLM使用Pinecone和ChromaDB来处理矢量嵌入,并使用OpenA…

Flask项目搭建及部署 —— Python

flask搭建及部署 pip 19.2.3 python 3.7.5 Flask 1.1.1 Flask-SQLAlchemy 2.4.1 Pika 1.1.0 Redis 3.3.11 flask-wtf 0.14.2 1、创建flask项目: 创建完成后整个项目结构树: app.py: 项⽬管理⽂件,通过它管理项⽬。 static: 存放静态…

Visio 2019 中文版安装下载教程【32/64位】,图文步骤详解,超简单,无套路!!!

文章目录 前言软件介绍软件下载安装步骤激活步骤 前言 本文针对visio 2019 的下载安装进行详细讲解,没有任何套路,大家可以放心使用,由于该类文章容易被和谐,大家可以收藏关注,以免迷路,若安装出现问题&am…

ubuntu重装系统后,安装cuda,cudnn

一、 先安装驱动,如果驱动安装不成功,会影响桌面,再重装系统还来得及,尝试了很多方法,还是用系统安装最靠谱: 首先进入Ubuntu搜索栏目,找到软件更新器的一个图标,点开之后是这样的。…

电力需求预测挑战赛笔记 Taks1 跑通baseline

#AI夏令营 #Datawhale #夏令营 赛题 一句话介绍赛题任务可以这样理解赛题: 【训练时序预测模型助力电力需求预测】 电力需求的准确预测对于电网的稳定运行、能源的有效管理以及可再生能源的整合至关重要。 赛题任务 给定多个房屋对应电力消耗历史 N 天的相关序列数…

网信大数据信用报告查询怎么查?网信大数据有什么作用?

随着互联网的快速发展,大数据技术已经广泛应用于各行各业。其中,网信大数据信用报告查询成为了许多人关注的焦点。那么,如何查询网信大数据信用报告呢?网信大数据又有哪些作用呢?本文将为您一一解答。 一、如何查询网信大数据信用报告? 要…

keepalive和haproxy

1、keepalive 1.1概念 调度器的高可用 vip地址主备之间的切换,主在工作时,vip地址只在主上,主停止工作,vip漂移到备服务器 在主备的优先级不变的情况下,主恢复工作,vip会飘回到主服务器 1、配优先级 …

java通过poi-tl导出word实战详细步骤

文章目录 与其他模版引擎对比1.引入maven依赖包2.新建Word文档exportWprd.docx模版3.编写导出word接口代码4.导出成果 poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让…

图论·Day01

P3371 P4779 P3371 【模板】单源最短路径(弱化版) 注意的点: 边有重复,选择最小边!对于SPFA算法容易出现重大BUG,没有负权值的边时不要使用!!! 70分代码 朴素板dijsk…

100 个网络基础知识普及,看完成半个网络高手!

1)什么是链接? 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2)OSI 参考模型的层次是什么? 有 7 个 OSI 层:物理层,数据链路层,网络层&#xff0…