MySQL - 事务日志

目录

1. redo日志

1.1 为什么需要REDO日志

1.2 REDO日志的好处、特点

1. 好处

2. 特点

1.3 redo的组成

1.4 redo的整体流程

1.5 redo log的刷盘策略

1.6 不同刷盘策略演示

1. 流程图

​编辑2. 举例

1.7 写入redo log buffer 过程

1.8 redo log file 

1. 相关参数设置

2. 日志文件组

3. checkpoint

2. Undo日志 

2.1 如何理解Undo日志

2.2 Undo日志的作用

2.3 undo的存储结构

1. 回滚段与undo页

2. 回滚段与事务

3. 回滚段中的数据分类

2.4 undo的类型

2.5 undo log的生命周期

1. 简要生成过程

2. 详细生成过程

3. undo log是如何回滚的

4. undo log的删除

2.6 小结

事务有4种特性:原子性、一致性、隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢?

  • 事务的隔离性由 锁机制 实现。
  • 而事务的原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。
    • REDO LOG 称为 重做日志 ,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持 久性。
    • UNDO LOG 称为 回滚日志 ,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。

有的DBA或许会认为 UNDO 是 REDO 的逆过程,其实不然。

1. redo日志

1.1 为什么需要REDO日志

一方面,缓冲池可以帮助我们消除CPU和磁盘之间的鸿沟,checkpoint机制可以保证数据的最终落盘,然 而由于checkpoint 并不是每次变更的时候就触发 的,而是master线程隔一段时间去处理的。所以最坏的情 况就是事务提交后,刚写完缓冲池,数据库宕机了,那么这段数据就是丢失的,无法恢复。

另一方面,事务包含 持久性 的特性,就是说对于一个已经提交的事务,在事务提交后即使系统发生了崩 溃,这个事务对数据库中所做的更改也不能丢失。

那么如何保证这个持久性呢? 一个简单的做法 :在事务提交完成之前把该事务所修改的所有页面都刷新 到磁盘,但是这个简单粗暴的做法有些问题

另一个解决的思路 :我们只是想让已经提交了的事务对数据库中数据所做的修改永久生效,即使后来系 统崩溃,在重启后也能把这种修改恢复出来。所以我们其实没有必要在每次事务提交时就把该事务在内 存中修改过的全部页面刷新到磁盘,只需要把 修改 了哪些东西 记录一下 就好。比如,某个事务将系统 表空间中 第10号 页面中偏移量为 100 处的那个字节的值 1 改成 2 。我们只需要记录一下:将第0号表 空间的10号页面的偏移量为100处的值更新为 2 。

1.2 REDO日志的好处、特点

1. 好处

  • redo日志降低了刷盘频率
  • redo日志占用的空间非常小

2. 特点

  • redo日志是顺序写入磁盘的
  • 事务执行过程中,redo log不断记录

1.3 redo的组成

Redo log可以简单分为以下两个部分:

  • 重做日志的缓冲 (redo log buffer) ,保存在内存中,是易失的。

参数设置:innodb_log_buffer_size:

redo log buffer 大小,默认 16M ,最大值是4096M,最小值为1M。

  • 重做日志文件 (redo log file) ,保存在硬盘中,是持久的。

1.4 redo的整体流程

以一个更新事务为例,redo log 流转过程,如下图所示:

第1步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝

第2步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值

第3步:当事务commit时,将redo log buffer中的内容刷新到 redo log file,对 redo log file采用追加 写的方式

第4步:定期将内存中修改的数据刷新到磁盘中

体会: Write-Ahead Log(预先日志持久化):在持久化一个数据页之前,先将内存中相应的日志页持久化。

1.5 redo log的刷盘策略

redo log的写入并不是直接写入磁盘的,InnoDB引擎会在写redo log的时候先写redo log buffer,之后以 一 定的频率 刷入到真正的redo log file 中。这里的一定频率怎么看待呢?这就是我们要说的刷盘策略。

注意,redo log buffer刷盘到redo log file的过程并不是真正的刷到磁盘中去,只是刷入到 文件系统缓存 (page cache)中去(这是现代操作系统为了提高文件写入效率做的一个优化),真正的写入会交给系 统自己来决定(比如page cache足够大了)。那么对于InnoDB来说就存在一个问题,如果交给系统来同 步,同样如果系统宕机,那么数据也丢失了(虽然整个系统宕机的概率还是比较小的)。

针对这种情况,InnoDB给出 innodb_flush_log_at_trx_commit 参数,该参数控制 commit提交事务 时,如何将 redo log buffer 中的日志刷新到 redo log file 中。它支持三种策略:

  • 设置为0 :表示每次事务提交时不进行刷盘操作。(系统默认master thread每隔1s进行一次重做日 志的同步)
  • 设置为1 :表示每次事务提交时都将进行同步,刷盘操作( 默认值
  • 设置为2 :表示每次事务提交时都只把 redo log buffer 内容写入 page cache,不进行同步。由os自 己决定什么时候同步到磁盘文件。

1.6 不同刷盘策略演示

1. 流程图

2. 举例

1.7 写入redo log buffer 过程

1. 补充概念:Mini-Transaction

一个事务可以包含若干条语句,每一条语句其实是由若干个 mtr 组成,每一个 mtr 又可以包含若干条 redo日志,画个图表示它们的关系就是这样:

2. redo 日志写入log buffer

每个mtr都会产生一组redo日志,用示意图来描述一下这些mtr产生的日志情况:

3. redo log block的结构图

 

1.8 redo log file 

1. 相关参数设置

  • innodb_log_group_home_dir :指定 redo log 文件组所在的路径,默认值为 ./ ,表示在数据库 的数据目录下。MySQL的默认数据目录( var/lib/mysql )下默认有两个名为 ib_logfile0 ib_logfile1 的文件,log buffer中的日志默认情况下就是刷新到这两个磁盘文件中。此redo日志 文件位置还可以修改。
  • innodb_log_files_in_group:指明redo log file的个数,命名方式如:ib_logfile0,iblogfile1... iblogfilen。默认2个,最大100个。
mysql> show variables like 'innodb_log_files_in_group';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2 |
+---------------------------+-------+
#ib_logfile0
#ib_logfile1
  • innodb_flush_log_at_trx_commit:控制 redo log 刷新到磁盘的策略,默认为1。
  • innodb_log_file_size:单个 redo log 文件设置大小,默认值为 48M 。最大值为512G,注意最大值 指的是整个 redo log 系列文件之和,即(innodb_log_files_in_group * innodb_log_file_size )不能大 于最大值512G。
mysql> show variables like 'innodb_log_file_size';
+----------------------+----------+
| Variable_name | Value |
+----------------------+----------+
| innodb_log_file_size | 50331648 |
+----------------------+----------+

根据业务修改其大小,以便容纳较大的事务。编辑my.cnf文件并重启数据库生效,如下所示

[root@localhost ~]# vim /etc/my.cnf
innodb_log_file_size=200M

2. 日志文件组

总共的redo日志文件大小其实就是: innodb_log_file_size × innodb_log_files_in_group 。 采用循环使用的方式向redo日志文件组里写数据的话,会导致后写入的redo日志覆盖掉前边写的redo日 志?当然!所以InnoDB的设计者提出了checkpoint的概念。

3. checkpoint

如果 write pos 追上 checkpoint ,表示日志文件组满了,这时候不能再写入新的 redo log记录,MySQL 得 停下来,清空一些记录,把 checkpoint 推进一下。

2. Undo日志 

redo log是事务持久性的保证,undo log是事务原子性的保证。在事务中 更新数据前置操作 其实是要 先写入一个 undo log

2.1 如何理解Undo日志

事务需要保证 原子性 ,也就是事务中的操作要么全部完成,要么什么也不做。但有时候事务执行到一半 会出现一些情况,比如:

  • 情况一:事务执行过程中可能遇到各种错误,比如 服务器本身的错误操作系统错误 ,甚至是突 然 断电 导致的错误。
  • 情况二:程序员可以在事务执行过程中手动输入 ROLLBACK 语句结束当前事务的执行。

以上情况出现,我们需要把数据改回原先的样子,这个过程称之为 回滚 ,这样就可以造成一个假象:这 个事务看起来什么都没做,所以符合 原子性 要求。

2.2 Undo日志的作用

  • 作用1:回滚数据
  • 作用2:MVCC

2.3 undo的存储结构

1. 回滚段与undo页

InnoDB对undo log的管理采用段的方式,也就是 回滚段(rollback segment) 。每个回滚段记录了 1024 undo log segment ,而在每个undo log segment段中进行 undo页 的申请。

  • InnoDB1.1版本之前 (不包括1.1版本),只有一个rollback segment,因此支持同时在线的事务 限制为 1024 。虽然对绝大多数的应用来说都已经够用。
  • 从1.1版本开始InnoDB支持最大 128个rollback segment ,故其支持同时在线的事务限制提高到 了 128*1024
mysql> show variables like 'innodb_undo_logs';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_undo_logs | 128 |
+------------------+-------+

2. 回滚段与事务

  1. 每个事务只会使用一个回滚段,一个回滚段在同一时刻可能会服务于多个事务。
  2. 当一个事务开始的时候,会制定一个回滚段,在事务进行的过程中,当数据被修改时,原始的数 据会被复制到回滚段。
  3. 在回滚段中,事务会不断填充盘区,直到事务结束或所有的空间被用完。如果当前的盘区不够 用,事务会在段中请求扩展下一个盘区,如果所有已分配的盘区都被用完,事务会覆盖最初的盘 区或者在回滚段允许的情况下扩展新的盘区来使用。
  4. 回滚段存在于undo表空间中,在数据库中可以存在多个undo表空间,但同一时刻只能使用一个 undo表空间。
  5. 当事务提交时,InnoDB存储引擎会做以下两件事情:
    1. 将undo log放入列表中,以供之后的purge操作  
    2. 判断undo log所在的页是否可以重用,若可以分配给下个事务使用

3. 回滚段中的数据分类

  1. 未提交的回滚数据(uncommitted undo information) 
  2. 已经提交但未过期的回滚数据(committed undo information) 
  3. 事务已经提交并过期的数据(expired undo information)

2.4 undo的类型

在InnoDB存储引擎中,undo log分为:

  • insert undo log
  • update undo log

2.5 undo log的生命周期

1. 简要生成过程

只有Buffer Pool的流程:

有了Redo Log和Undo Log之后:

2. 详细生成过程

 当我们执行INSERT时:

begin

INSERT INTO user (name) VALUES ("tom")

当我们执行UPDATE时:

UPDATE user SET id=2 WHERE id=1

3. undo log是如何回滚的

以上面的例子来说,假设执行rollback,那么对应的流程应该是这样:

  1. 通过undo no=3的日志把id=2的数据删除
  2. 通过undo no=2的日志把id=1的数据的deletemark还原成0
  3. 通过undo no=1的日志把id=1的数据的name还原成Tom
  4. 通过undo no=0的日志把id=1的数据删除

4. undo log的删除

  • 针对于insert undo log

 因为insert操作的记录,只对事务本身可见,对其他事务不可见。故该undo log可以在事务提交后直接删 除,不需要进行purge操作。

  • 针对于update undo log

该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等 待purge线程进行最后的删除。

2.6 小结

undo log是逻辑日志,对事务回滚时,只是将数据库逻辑地恢复到原来的样子。

redo log是物理日志,记录的是数据页的物理变化,undo log不是redo log的逆过程。

 

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

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

相关文章

matlab倒立摆小车LQR控制动画

1、内容简介 略 54-可以交流、咨询、答疑 2、内容说明 略 摆杆长度为 L,质量为 m 的单级倒立摆(摆杆的质心在杆的中心处),小车的质量为 M。在水平方向施加控制力 u,相对参考系产生位移为 y。为了简化问题并且保其实质不变,忽…

【SelectIO】bitslice原语学习记录

基本概念 在Ultrascale (plus)系列上的FPGA中,Xilinx引入了bitslice硬核,它取代了7系列上的IDELAYCTRL/IODELAY/IOSERDES/IODDR系列硬核,用于为HP(High Performance)类型Bank上的IO接口提供串并转化、信号延时、三态控…

【k8s资源调度-HPA(自动扩缩容)】

1、HPA可以做什么? 通过观察pod的cpu、内存使用率或自定义metrics指标进行自动的扩容或缩容pod的数量。通常用于Deployment,不适用于无法扩/缩容的对象,如DaemonSet。控制管理器每隔30s(可以通过-horizontal-pod-autoscaler–sync-period修改…

特征选择|一种提升预测模型性能的方法(原理及其优化实现,Matlab)

文章来源于我的个人公众号:KAU的云实验台,主要更新智能优化算法的原理、应用、改进 如今,生成的数据集呈指数级增长,这将产生具有大量特征和样本的数据集,而显然,某些特征是不相关/冗余的,它们…

springBoot整合Redis(一、Jedis操作Redis)

在springboot环境下连接redis的方法有很多,首先最简单的就是直接通过jedis类来连接,jedis类就相当于是redis的客户端表示。 但是因为现在比较常用的是:StringRedisTemplate和RedisTemplate,所以jedis只做简单的介绍。 一、Jedis…

Langchain-Chatchat部署总结

项目地址: https://github.com/chatchat-space/Langchain-Chatchat 整体安装比较方便,在阿里云购买云主机,购买的国外站点机器, 该项目运行最佳坏境为 Linux Ubuntu 22.04.5Python 版本 3.11.7CUDA 版本: 12.1torch2.1.2 使…

Spring的优点

1.方便解耦,简化开发 Spring就是一个容器,可以将所有对象创建和关系维护交给Spring管理。 2.AOP编程支持 面向切面编程,方便实现程序进行权限拦截,运行监控等功能。 3.声明式事务的支持 通过配置完成事务的管理,…

Web UI自动化测试原理

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

每日五道java面试题之spring篇(六)

目录: 第一题 ApplicationContext通常的实现是什么?第二题 什么是Spring的依赖注入?第三题 依赖注入的基本原则第四题 依赖注入有什么优势?第五题 有哪些不同类型的依赖注入实现方式? 第一题 ApplicationContext通常的…

d3dcompiler_47.dll是什么,电脑出现d3dcompiler_47.dll丢失如何解决

当打开软件时提示“d3dcompiler_47.dll丢失”时,用户通常会看到类似于以下的错误消息: “无法启动此程序,因为计算机中丢失了d3dcompiler_47.dll。尝试重新安装该程序以解决此问题。” “找不到d3dcompiler_47.dll文件,因此应用…

[C++]虚函数用法

讲虚函数之前先讲讲面向对象的三大特性:封装、继承、多态。 1、封装 封装是指将数据(属性)和操作数据的方法(函数)封装在一个单元中,这个单元就是类。封装的主要目的是隐藏类的内部实现细节,只…

Java内部类的使用与应用

内部类的使用与应用 1. 内部类用法 普通内部类: 实例化内部类对象需要先实例化外部类对象,然后再通过OuterClassName.new InnerClassName()方式实例化内部类。内部类对象在创建后会与外部类对象秘密链接,因此无法独立于外部类创建内部类对象…

JWT学习笔记

了解 JWT Token 释义及使用 | Authing 文档 JSON Web Token Introduction - jwt.io JSON Web Token (JWT,RFC 7519 (opens new window)),是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519)。该 token 被设计为紧凑…

微服务-微服务Spring Security OAuth 2实战

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

高等数学(极限)

目录 一、数列 二、极限 2.1 讲解 2.2 例题 一、数列 按照一定次数排列的一列数: 其中 叫做通项。 对于数列,如果当n无限增大时,其通项无限接近于一个常数A,则称该数列以A为极限或称数列收敛于A,否则称数列为发散…

OpenCV(2)

1.OpenCV的模块 其中core、highgui、imgproc是最基础的模块,该课程主要是围绕这几个模块展开的,分别介绍如下: core模块实现了最核心的数据结构及其基本运算,如绘图函数、数组操作相关函数等。highgui模块实现了视频与图像的读取…

【JVM】计数器引用和可达性分析

📝个人主页:五敷有你 🔥系列专栏:JVM ⛺️稳中求进,晒太阳 C/C的内存管理 在C/C这类没有自动垃圾回收机制的语言中,一个对象如果不再使用,需要手动释放,否则就会出现内存泄漏…

一文get,最容易碰上的接口自动化测试问题汇总

本篇文章分享几个接口自动化用例编写过程遇到的问题总结,希望能对初次探索接口自动化测试的小伙伴们解决问题上提供一小部分思路。 sql语句内容出现错误 空格:由于有些字段判断是变量,需要将sql拼接起来,但是在拼接字符串时没有…

对象池模板

概述 对象池的引入也是嵌入式开发的常用方法,也是内存预分配的一种,主要是用来隐藏全局对象的跟踪,通常预内存分配是通过数组来实现。 CMake配置 cmake_minimum_required(VERSION 3.5.1)project(objpool)add_executable(objpool objpool.cp…

C语言《数据结构与算法》安排教学计划课设

背景: 10、安排教学计划 (1) 问题描述。 学校每学期开设的课程是有先后顺序的,如计算机专业:开设《数据结构》课程之前,必须先开设《C语言程序设计》和《离散数学》课程,这种课程开设的先后顺序称为先行、后继课程关…