mysql之日志

news2024/11/17 12:48:32

前言

一条数据在更新过程当中,如果中途 mysql crash 了,mysql 是如何保证数据的一致性和持久性的?在这个过程中 mysql 的日志系统起到了至关重要的作用。本文将会介绍 mysql 中的 undo log、redo log 和 bin log 在这其中的作用。

buffer pool

在数据更新的时候,数据并不是实时同步到硬盘中,而是在一块缓存 buffer pool 中更新,如果缓存中没有查询到该数据,则从磁盘中加载到 buffer pool 中。

当然,缓存的作用是为了提高 IO 性能,可以通过将数据先保留在缓存中,然后在适当的时机,批量写入到硬盘中。

并且在查询数据时,先是从缓存中进行查询,不用去磁盘中查找,减少 IO 的操作,加快查询的速度。

undo log

我们知道 InnoDB 是支持事务的,在事务提交失败时,是会回滚到执行之前的状态,那么肯定是需要保存之前的状态才可以进行恢复的,这个就是通过 undo log 来实现的。

在数据写入 buffer pool 的同时会将更新前的数据保存在 undo log 中,通过该日志语句便可以在事务回滚时,恢复到之前的状态。

redo log

redo log 的作用

再回到 buffer pool ,因为它是缓存,是在内存中,所有它的缺点也显而易见,那就是当服务器宕机中,缓存中的数据会丢失,那么 mysql 是如何保证数据的持久性呢?这个时候就要来介绍介绍 redo log 了。

在数据更新到 buffer pool 后,这个时候会将更新后的数据记录到 redo log buffer 中,这个也是一个缓存区,它当然也具备了缓存优缺点,并且默认是在提交事务的时候写入到 redo log 中,刷盘的策略可以根据 innodb_flush_log_at_trx_commit 来设置

  • 0,不刷入磁盘
  • 1,立即刷入磁盘(默认)
  • 2,先刷入到 os cache 中

因为 redo log 是顺序写入,所以 IO 性能不会太差。

当 buffer pool 中的数据还没有写入到磁盘中时,发生了宕机,当 mysql 重启时,会读取已经持久化 redo log 中的数据,再恢复到 buffer pool 中。

在开启事务准备更新一条记录时,InnoDB 会先在 buffer pool 中更新数据,然后将更新后的数据记录到 redo log buffer 中,这也是一个缓存。当然这个时候也是会发生宕机,但是没关系,如果该部分数据丢失,则认为该次事务提交失败,数据会恢复到之前的状态。

redo log文件结构

redolog 是由多个固定大小的文件组成的一个环形结构,并在这个环形结构中不断的写入与覆盖的过程。

  • write pos:记录当前的位置
  • checkpoint:当前要擦除的位置

当有新的 redo log 写入时,从 wirte pos 位置往后写,而 check point 是上一次已经刷入磁盘的数据的位置,也是要不断的往后推进,然后将数据刷入磁盘中。

binlog

是在 mysql 层级记录的日志,主要是用于主从复制和数据恢复,可以通过某个时间的全量备份+binlog 来恢复到任意时间内的状态。

和 redo log 的区别

性质redo logbin log
实现innodb 独有实现mysql server 层级实现,所有的引擎都可以使用
内容物理 log, 记录的是“在某个数据页上做了什么修改”逻辑 log,给 ID=2 这一行的 c 字段加 1
写入循环写入追加写,写到一定大小切换下一个文件继续写
应用崩溃恢复(crash-safe)主从同步,数据恢复

两阶段提交

为什么需要两阶段提交?

是为了让 redo log 和 bin log 保持逻辑一致性。

  1. 如果先写 redolog 后写 bin log。假设 redo log 写完,写 bin log 时 crash 了。

因为 redo log 写完了,所以即使系统崩溃,也可以恢复数据,但是 bin log 没写完 crash 了,这个时候 bin log 中少了该条语句,因此数据备份的时候,如果使用了该 bin log 则会少一次更新。

  1. 如果先写 bin log 后写 redo log。假设 bin log 写完,写 redo log 时 crash 了。

因为 redo log 没写完,所以该事务没有生效,但是 binlog 中已经有该条记录,所以使用 bin log 时,会多出一个事务,与原来的数据不一致。

所以使用两阶段提交可以解决上面两种场景。

两阶段提交的实现逻辑

  1. 在更新数据时,会先在 redo log 中记录当前更新的数据,并且标记为 prepare 状态
  2. binlog 再进行写入
  3. 事务提交时, redo log 再将该条记录标记为 commit 状态并且刷入到磁盘中。

通过 prepare 和 commit 两种状态来完成两阶段的提交实现。

验证两阶段提交

  1. 如果在两阶段提交的第一步后发生 crash,也就是 redo log 已经更新了数据并且为 Prepare 状态,但是 binlog 还未写入就出现了 crash,这个时候,mysql 重启后,因为 redo log 未 commit,可以通过回滚将数据恢复。
  2. 如果在第二步发生 crash,也就是 redo log 为 prepare 状态,并且 binlog 已经写入,但是这时候出现了 crash,在 mysql 重启后,因为 binlog 已经有了记录,所以会继续提交该事务,否则 bin log 中数据新增了一条,而 redo log 没提交则可能发生两者数据不一致的情况。

相关链接

  • 一条 SQL 的执行过程详解
  • 基于Redo Log和Undo Log的MySQL崩溃恢复流程

欢迎关注,互相学习,共同进步~

我的个人博客
公众号:编程黑洞

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

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

相关文章

230109-MacOS解决brew安装慢的问题

MacOS解决brew安装慢的问题 原文请移步参考: https://www.zhihu.com/question/46963138 cd "$(brew --repo)" git remote set-url origin https://mirrors.ustc.edu.cn/brew.gitecho export HOMEBREW_BOTTLE_DOMAINhttps://mirrors.ustc.edu.cn/homebrew…

2022年度大赏 | UWA问答精选

UWA每周推送的知识型栏目《厚积薄发 | 技术分享》已经伴随大家走过了304个工作周。精选了2022年十大精彩问答分享给大家,期待2022年UWA问答继续有您的陪伴。 Q1:动态获取URP设置里自定义的RenderFeatures 我们在URP项目中自定义了多个RenderFeatures去实…

2022年度总结,以及2023的全新展望

时光总是在你的不经意间流逝,无法挽留;留得住的是你过去的努力和回忆,它也许充斥着快乐、忧伤、病痛等等。俗话说得好“笑一笑十年少”,那么我希望与快乐随行,让痛苦尘封记忆。让我们总结过去,展望未来&…

Python tkinter -- 第18章 画布控件之矩形

18.2.20 create_rectangle(bbox, **options) 根据限定矩形 bbox,在画布上创建一个矩形。新创建的对象位于显示的最前端。 (1)bbox:定义要创建对象的边界(x1, y1, x2, y2) (2)options: 选项的具体…

ICESat数据下载

ICESat数据下载1. ICESat简介2. ICESat数据产品2.1 GLA01数据2.2 GLA14数据3. 数据下载4. 总结1. ICESat简介 2003年美国国家航空航天局NASA ( National Aeronautics and SpaceAdministration)发射冰、云和陆地高程卫星ICESat,其上搭载的地球科学激光测高系统GLAS是…

基于YOLOv5的智能人脸数据标注工具源码,实现人脸数据标注自动化,可导出PASCAL VOC XML、MS COCO JSON

基于YOLOv5的智能人脸数据标注工具,实现人脸数据标注自动化 可自定义人脸检测模型、可导出多种格式标签,包括PASCAL VOC XML、MS COCO JSON、YOLO TXT 下载地址:基于YOLOv5的智能人脸数据标注工具源码,实现人脸数据标注自动化 …

智能黑白图像自动上色——C++实现

前言 《Colorful Image Colorization》是加里福利亚大学Richard Zhang发表在ECCV 2016上的文章,论文主要解决的问题是给灰度图的自动着色,算法并不是为恢复灰度图的真实颜色,而是用灰度图中物体的纹理、语义等信息作为线索,来预测…

Gradle学习笔记01

一、Gradle视频介绍新一代构建工具Gradle,提到项目自动化构建工具,首先提到的是Maven。现在谈谈Gradle与Maven之间的差异:同样作为项目自动化构建工具,Maven更侧重于项目jar包的管理,而Gradle侧重于项目的构建&#xf…

卷积层、卷积层里的填充和步幅

多层感知机正式总结卷积层之前,先把上次多层感知机落下的一点内容补一补。几个概念:训练数据集:训练模型参数。验证数据集:选择模型超参数。训练误差:模型在训练数据上的误差。泛化误差:模型在新数据上的误…

Linux常用命令——lftp命令

在线Linux命令查询工具 lftp 优秀的文件客户端程序 补充说明 lftp命令是一款优秀的文件客户端程序,它支持ftp、SETP、HTTP和FTPs等多种文件传输协议。lftp支持tab自动补全,记不得命令双击tab键,就可以看到可能的选项了。 语法 lftp(选项…

基于PCAP搭建软HUB实现物联网在线调试

完整工程可从以下地址签出: https://gitcode.net/coloreaglestdio/pcaphub.git 1.需求场景 在调试嵌入式物联设备时,尤其是在多个以太网物联设备交错通信的情况下,很难通过在捉襟见肘的嵌入式系统上进行数据记录与调试。如果设备连接的是一…

基于Kintex-7 FPGA的核心板电路设计

1. 引言Field Programmable GateArray(简称,FPGA)于1985年由XILINX创始人之一Ross Freeman发明,第一颗FPGA芯片XC2064为XILINX所发明,FPGA一经发明,后续的发展速度之快,超出大多数人的想象&…

系分 - 案例分析 - 需求获取

个人总结,仅供参考,欢迎加好友一起讨论 文章目录系分 - 案例分析 - 需求获取需求获取方法典型例题题目描述参考答案系分 - 案例分析 - 需求获取 需求获取方法 用户访谈 工作内容要点准备访谈步骤:1 确定访谈目的。2 确定访谈哪些用户。3 准…

PHP 文件上传

通过 PHP,可以把文件上传到服务器。 本章节实例在 test 项目下完成,目录结构为: test |-----upload # 文件上传的目录 |-----form.html # 表单文件 |-----upload_file.php # php 上传代码 源码下载 创建一个文件上…

获取Git权限的三种方式

获取Git权限的三种方式写在最前1. HTTPS配合用户名和密码访问Git1.1 获取当前项目的用户和密码1.2 通过临时用户获取Git权限2. HTTPS配合token访问Git2.1 创建token2.2 HTTPS配合token获取Git权限3. SSH访问Git3.1 生成SSH公钥和私钥3.2 使用SSH获取Git权限写在最前 本文以为Az…

力扣(LeetCode)375. 猜数字大小 II(2023.01.08)

我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字。 你来猜我选了哪个数字。 如果你猜到正确的数字,就会 赢得游戏 。 如果你猜错了,那么我会告诉你,我选的数字比你的 更大或者更小 ,并…

接口测试——postman和Jemter

接口测试——postman和Jemterpostmanpostman工作原理postman入门postman的基础用法postman的高级用法使用postman管理测试用例批量执行测试用例postman断言环境变量和全局变量postman关联postman请求前置脚本postman参数化及生成测试报告参数化与数据驱动postman生成测试报告je…

(十五)内部类简述

目录 1.概述: 2.内部类之一:静态内部类 3.内部类之二:成员内部类 4.内部类之三:局部内部类 5.内部类之四:匿名内部类 1.概述: 内部类就是定义在一个类里面的类,里面的类可以理解成(寄生)。 2.内部类的使用场景、作用: ①当一个事务的内部,还…

GIT zip下载和clone下载的代码不一致?

问题场景 今天我在下载公司项目的时候遇到了一个问题,我选择了一个分支a,通过下载zip的代码发现是全的,而我通过clone的时候发现显示的是master上的代码 原因 其实是clone下载下来了,但是我idea中分支打开时默认选择的是master分支…

Compose 动画入门 (二) : 为什么animateDpAsState要用val ? MutableState和State有什么区别 ?

1. 前言 我们首先来实现一个Compose的动画(animateDpAsState) var big by remember {mutableStateOf(false) } val size by animateDpAsState(if (big) 100.dp else 50.dp)Box(Modifier.size(size).background(Color.Blue).clickable {big !big}) {}运行程序,来看…