目录
Redo Log
redo log刷盘策略
其他参数
Undo Log
回滚段与undo页
Undo类型
undo log的生命周期
详细生成过程
undo log是如何回滚的
扩展
bin log
写入时机
binlog与redo log对比
两阶段提交
首页 数据库 mysql教程 MySQL日志之redo log和undo log的知识点有哪些

MySQL日志之redo log和undo log的知识点有哪些

May 28, 2023 pm 08:02 PM
mysql redo log undo log

Redo Log

REDO LOG称为重做日志 ,当MySQL服务器意外崩溃或者宕机后,保证已经提交的事务持久化到磁盘中(持久性)。

InnoDB是以页为单位去操作记录的,增删改查都会加载整个页到buffer pool中(磁盘->内存),事务中的修改操作并不是直接修改磁盘中的数据,而是先修改内存中buffer pool中的数据,后台线程每隔一段时间再异步刷新到磁盘中。

buffer pool:可存放索引、数据,可加速读写,直接在内存中操作数据页,有专门的线程去把buffer pool中的脏页写入磁盘。

为什么不直接修改磁盘中的数据?

因为直接修改磁盘数据的话,它是随机IO,修改的数据分布在磁盘中不同的位置,需要来回的查找,所以命中率低,消耗大,而且一个小小的修改就不得不将整个页刷新到磁盘,利用率低;

与之相对的是顺序IO,磁盘的数据分布在磁盘的一块,所以省去了查找的过程,节省寻道时间。

使用后台线程以一定的频率去刷新磁盘可以降低随机IO的频率,增加吞吐量,这是使用buffer pool的根本原因。

修改内存再异步同步到磁盘的问题:

因为buffer pool是在内存中的区域,系统意外崩溃的话数据有可能会丢失,有些脏数据可能会来不及刷新到磁盘,事务的持久性得不到保证。因此,引入了redo log。修改数据时,额外记录一次日志,内容是xx页xx偏移量发生了xx变化,当系统崩溃时可以根据日志内容进行恢复。

写日志和直接刷新磁盘的区别是:写日志是追加写入,顺序IO,速度更快,且写入的内容相对更小

redo log由两部分组成:

  1. redo log buffer(内存层面,默认16M,通过innodb_log_buffer_size参数可修改)

  2. redo log file(持久化的,磁盘层面)

修改操作大致过程:

MySQL日志之redo log和undo log的知识点有哪些

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

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

第3步:默认在事务提交后将redo log buffer中的内容刷新到redo log file,对redo log file采用追加写的方式

第4步:定期将内存中修改的数据刷新到磁盘中(这里说的是那些还没及时被后台线程刷盘的脏数据)

通常所说的Write-Ahead Log(预先日志持久化)指的是在持久化一个数据页之前,先将内存中相应的日志页持久化。

redo log的好处:

  • 减少了磁盘刷新频率

  • redo log占用空间小

  • redo log写入速度快

redo log一定能保证事务的持久性吗?

不一定,这要根据redo log的刷盘策略决定,因为redo log buffer同样是在内存中,如果提交事务之后,redo log buffer还没来得及将数据刷新到redo log file进行持久化,此时发生宕机照样会丢失数据。如何解决?刷盘策略。

redo log刷盘策略

InnoDB中给出了innodb_flush_log_at_trx_commit参数控制redo log buffer刷新到redo log file时的三种策略:

  • 值为0:开启一个后台线程,每1s刷新一次到磁盘中,提交事务时就不需要进行刷新了

  • 值为1:commit时再进行同步刷新(默认值),真正保证数据的持久性

  • 值为2:commit的时候,只是刷新进os的内核缓冲区,具体的刷盘时机不确定

值为0的情况:

MySQL日志之redo log和undo log的知识点有哪些

因为有1s的间隔,所以最坏情况下会丢失1秒的数据。

值为1的情况:

MySQL日志之redo log和undo log的知识点有哪些

commit时需要先主动刷新redo log buffer到redo log file,如果中途宕机了,事务也就失败了,不会有任何损失,真正能保证事务的持久性。但是效率最差。

值为2的情况:是根据os决定。

可以调整为0或2提高事务的性能,但是丧失了ACID特性

其他参数

  • innodb_log_group_home_dir:指定 redo log文件组所在的路径,默认值为 ./ ,表示在数据库的数据目录下。MySQL的默认数据目录下默认有两个名为ib_logfile0和ib_logfile1的文件,log buffer中的日志默认情况下就是刷新到这两个磁盘文件中。

  • innodb_log_files_in_group:指明redo log file的个数,命名方式如:ib_logfile0,iblogfile1... iblogfilen。默认2个,最大100个。

  • 默认情况下,innodb_log_file_size的大小被设置为48M,用于单个redo log文件的大小设置。

Undo Log

undo log用于保证事务的原子性和一致性。作用有两个:①提供回滚操作 ②多版本控制MVVC

回滚操作

前面redo log中说过,后台线程会不定时的去刷新buffer pool中的数据到磁盘,但是如果该事务执行期间出现各种错误(宕机)或者执行rollback语句,那么前面刷进去的操作都是需要回滚的,保证原子性,undo log就是提供事务回滚的。

MVVC

当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据——快照读。

快照读:SQL读取的数据是历史版本,不用加锁,普通的SELECT就是快照读。

undo log的组成部分:

  • 当insert记录的时候,必须将该记录的主键值记录下来,这样才可以回滚时删除该数据。

  • 当update记录的时候,必须将修改的旧值全部记录下来,回滚时更新为旧值即可。

  • 当delete的时候,必须将所有的记录都记录下来,回滚时再重新插入该内容的记录。

select操作不会产生undo log

回滚段与undo页

在InnoDB存储引擎中,undo log使用rollback segment回滚段进行存储,每隔回滚段包含了1024个undo log segment。 MySQL5.5之后,一共有128个回滚段。即总共可以记录128 * 1024个undo操作。

每个事务只会使用一个回滚段,一个回滚段在同一时刻可能会服务于多个事务。

删除undo log不能立即执行在提交事务后,因为有些事务可能想要读取先前的数据版本(快照读)。所以事务提交时将undo log放入一个链表中,称为版本链,undo log的删除与否由一个称为purge的线程判断。

Undo类型

undo log分为:

insert undo log

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

update undo log

Undo logs record the changes made to delete and update operations.。为了支持MVCC机制,因此不能在事务提交时立即删除undo log。在提交时,将其加入撤销日志链表,等待清理线程进行最终的删除。

undo log的生命周期

假设有2个数值,分别为A=1和B=2,然后某个事务将A修改为3,B修改为4,修改过程可简化为:

1.begin
2.记录A=1到undo log
3.update A=3
4.记录A=3到redo log
5.记录B=2到undo log
6.update B=4
7.记录B=4到redo log
8.将redo log刷新到磁盘
9.commit

  • 在1-8步骤的任意一步系统宕机,事务未提交,该事务就不会对磁盘上的数据做任何影响。

  • 如果在8-9之间宕机,恢复之后可以选择回滚,也可以选择继续完成事务提交,因为此时redo log已经持久化。

  • 若在9之后系统宕机,内存映射中变更的数据还来不及刷回磁盘,那么系统恢复之后,可以根据redo log把数据刷回磁盘。

MySQL日志之redo log和undo log的知识点有哪些

详细生成过程

对于InnoDB引擎来说,每个行记录除了记录本身的数据之外,还有几个隐藏的列:

  • DB_ROW_ID∶记录的主键id。

  • DB_TRX_ID:事务ID,当对某条记录发生修改时,就会将这个事务的Id记录其中。

  • DB_ROLL_PTR︰回滚指针,版本链中的指针。

MySQL日志之redo log和undo log的知识点有哪些

当我们执行INSERT时:

begin;
INSERT INTO user (name) VALUES ('tom');
登录后复制

每次插入数据都会创建一个插入操作的撤销日志,数据的回滚指针会指向此日志。undo log会记录undo log的序号、插入主键的列和值...,那么在进行rollback的时候,通过主键直接把对应的数据删除即可。

MySQL日志之redo log和undo log的知识点有哪些

当我们执行UPDATE时:

在执行更新操作时,会生成更新撤销日志,其中包括更新主键和不更新主键两种情况。假设现在进行更新操作:

UPDATE user SET name='Sun' WHERE id=1;
登录后复制

MySQL日志之redo log和undo log的知识点有哪些

这时会把新的undo log记录加入到版本链中,它的undo no是1,并且新的undo log的回滚指针会指向老的undo log (undo no=0)。

假设现在执行:

UPDATE user SET id=2 WHERE id=1;
登录后复制

MySQL日志之redo log和undo log的知识点有哪些

对于更新主键的操作,会先把原来的数据deletemark标识打开,这时并没有真正的删除数据,真正的删除会交给清理线程去判断,然后在后面插入一条新的数据,新的数据也会产生undo log,并且undo log的序号会递增。

可以发现每次对数据的变更都会产生一个undo log,当一条记录被变更多次时,那么就会产生多条undo log,undo log记录的是变更前的日志,并且每个undo log的序号是递增的,那么当要回滚的时候,按照序号依次向前推,就可以找到我们的原始数据了。

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的数据删除

MySQL MVVC多版本并发控制

扩展

bin log

Binary log, also known as update log, is a type of log file in binary format that records changes made to a database.。它记录了数据库所有执行的更新语句。

binlog主要应用场景:

  • 数据恢复:如果MySQL意外停止,可以通过该日志进行恢复、备份

  • 数据复制:master把它的二进制日志传递给slaves来达到master-slave数据的一致性

show variables like '%log_bin%';
登录后复制

查看bin log日志:

mysqlbinlog -v "/var/lib/mysql/binlog/xxx.000002"
登录后复制

使用日志恢复数据:

mysqlbinlog [option] filename|mysql –uuser -ppass;
登录后复制

删除二进制日志:

PURGE {MASTER | BINARY} LOGS TO ‘指定日志文件名'
PURGE {MASTER | BINARY} LOGS BEFORE ‘指定日期'
登录后复制

写入时机

事务执行过程中,先把日志写到bin log cache ,事务提交的时候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。

MySQL日志之redo log和undo log的知识点有哪些

binlog与redo log对比

  • InnoDB存储引擎层生成的redo log是一种物理日志,用于记录“对于哪些数据页进行了什么样的修改”。

  • 而binlog是逻辑日志,记录内容是语句的原始逻辑,类似于给ID=2这一行的c字段加1,属于服务层。

两个侧重点也不同, redo log让InnoDB有了崩溃恢复的能力,binlog保证了MySQL集群架构的数据一致性。

两阶段提交

在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样。

MySQL日志之redo log和undo log的知识点有哪些

redo log与binlog两份日志之间的逻辑不一致,会出现什么问题?

以update语句为例,假设id=2的记录,字段c值是0,把字段c值更新成1,SQL语句为update T set c=1 where id=2。

假设执行过程中写完redo log日志后,binlog日志写期间发生了异常,会出现什么情况呢?

MySQL日志之redo log和undo log的知识点有哪些

因为binlog异常中断写入,因此其中没有对应的修改记录。因此,之后用binlog日志恢复数据或者slave读取master的binlog时,就会少这一次更新,恢复出来的这一行c值是0,而原库因为redo log日志恢复,这一行c值是1,最终数据不一致。

MySQL日志之redo log和undo log的知识点有哪些

InnoDB存储引擎采用双阶段提交方案来处理两份日志之间的逻辑一致性问题。两阶段提交是指将redo log分为prepare和commit两个步骤进行处理。

让redo log和bin log最终的提交绑定到一起,前面说过的,事务commit时默认需要让redo log先同步完才算commit成功,所以如果绑定到一起的话,bin log也具有该特性了,就保证了数据不会丢失。

MySQL日志之redo log和undo log的知识点有哪些

使用两阶段提交后,写入binlog时发生异常也不会有影响,因为MySQL根据redo log日志恢复数据时发现redo log还处于prepare阶段,并且没有对应binlog日志,就会提交失败,回滚数据。

MySQL日志之redo log和undo log的知识点有哪些

另一个场景,redo log的commit阶段发生异常,那会不会回滚事务呢?

MySQL日志之redo log和undo log的知识点有哪些

并不会回滚事务,它会执行上图框住的逻辑,虽然redo log是处于prepare阶段,但是能通过事务id找到对应的binlog日志,所以MySQL认为是完整的,就会提交事务恢复数据。

以上是MySQL日志之redo log和undo log的知识点有哪些的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

MySQL:世界上最受欢迎的数据库的简介 MySQL:世界上最受欢迎的数据库的简介 Apr 12, 2025 am 12:18 AM

MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

MySQL的位置:数据库和编程 MySQL的位置:数据库和编程 Apr 13, 2025 am 12:18 AM

MySQL在数据库和编程中的地位非常重要,它是一个开源的关系型数据库管理系统,广泛应用于各种应用场景。1)MySQL提供高效的数据存储、组织和检索功能,支持Web、移动和企业级系统。2)它使用客户端-服务器架构,支持多种存储引擎和索引优化。3)基本用法包括创建表和插入数据,高级用法涉及多表JOIN和复杂查询。4)常见问题如SQL语法错误和性能问题可以通过EXPLAIN命令和慢查询日志调试。5)性能优化方法包括合理使用索引、优化查询和使用缓存,最佳实践包括使用事务和PreparedStatemen

为什么要使用mysql?利益和优势 为什么要使用mysql?利益和优势 Apr 12, 2025 am 12:17 AM

选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

apache怎么连接数据库 apache怎么连接数据库 Apr 13, 2025 pm 01:03 PM

Apache 连接数据库需要以下步骤:安装数据库驱动程序。配置 web.xml 文件以创建连接池。创建 JDBC 数据源,指定连接设置。从 Java 代码中使用 JDBC API 访问数据库,包括获取连接、创建语句、绑定参数、执行查询或更新以及处理结果。

docker怎么启动mysql docker怎么启动mysql Apr 15, 2025 pm 12:09 PM

在 Docker 中启动 MySQL 的过程包含以下步骤:拉取 MySQL 镜像创建并启动容器,设置根用户密码并映射端口验证连接创建数据库和用户授予对数据库的所有权限

MySQL的角色:Web应用程序中的数据库 MySQL的角色:Web应用程序中的数据库 Apr 17, 2025 am 12:23 AM

MySQL在Web应用中的主要作用是存储和管理数据。1.MySQL高效处理用户信息、产品目录和交易记录等数据。2.通过SQL查询,开发者能从数据库提取信息生成动态内容。3.MySQL基于客户端-服务器模型工作,确保查询速度可接受。

laravel入门实例 laravel入门实例 Apr 18, 2025 pm 12:45 PM

Laravel 是一款 PHP 框架,用于轻松构建 Web 应用程序。它提供一系列强大的功能,包括:安装: 使用 Composer 全局安装 Laravel CLI,并在项目目录中创建应用程序。路由: 在 routes/web.php 中定义 URL 和处理函数之间的关系。视图: 在 resources/views 中创建视图以呈现应用程序的界面。数据库集成: 提供与 MySQL 等数据库的开箱即用集成,并使用迁移来创建和修改表。模型和控制器: 模型表示数据库实体,控制器处理 HTTP 请求。

centos7如何安装mysql centos7如何安装mysql Apr 14, 2025 pm 08:30 PM

优雅安装 MySQL 的关键在于添加 MySQL 官方仓库。具体步骤如下:下载 MySQL 官方 GPG 密钥,防止钓鱼攻击。添加 MySQL 仓库文件:rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm更新 yum 仓库缓存:yum update安装 MySQL:yum install mysql-server启动 MySQL 服务:systemctl start mysqld设置开机自启动

See all articles