谈谈Redo Log和Undo Log

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 谈谈Redo Log和Undo Log

概述

在MYSQL中,日志是非常重要的,其中Redo log 和undo log都是引擎层(innodb)实现的日志,redo log 是重做日志,提供 前滚 操作,undo log 是回退日志,提供 回滚 操作。

  • redo Log是数据库引擎的一种日志,用于记录数据库的物理变更操作,例如数据页的修改。它以顺序方式记录,通常是追加写入磁盘上的日志文件。
  • undo Log是数据库引擎的一种日志,用于记录事务的回滚信息,即撤销已提交事务所做的修改操作。它记录了事务执行过程中旧值的备份,以支持事务的回滚操作。

回滚

未提交的事务,即事务未执行 commit。但事务内修改的脏页中,有一部分已刷盘。此时数据库宕机重启,需要回滚来将先前那部分已经刷盘的脏块从磁盘上撤销。

前滚

未完全提交的事务,即事务已经执行 commit,但该事务内修改的脏页中只有一部分数据被刷盘,另一部分还在 buffer pool,此时数据库宕机重启,就要用前滚来将未来得及刷盘的数据从 redo log 中恢复出来并刷盘。

Redo Log

MySQL 数据存在磁盘中,每次读写数据需做磁盘随机IO,并发场景下性能差。对此 MySQL 引入缓存 Buffer Pool 做优化。其包含磁盘中部分数据页(page)的映射,来缓解数据库的磁盘压力。

  • 缓冲池(bufer pool):主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度
  • 数据页(page):是InnoDB存储引擎磁盘管理的最小单元,每个页的大小默认为16KB。页中存储的是行数据

这个缓存中包含了磁盘中部分数据页(page)的映射,以此来缓解数据库的磁盘压力。当从数据库读数据时,首先从缓存中读取,如果缓存中没有,则从磁盘读取后放入缓存;当向数据库写入数据时,先向缓存写入,此时缓存中的数据页数据变更,这个数据页称为脏页Buffer Pool中修改完数据后会按照设定的更新策略,定期刷到磁盘中,这个过程称为刷脏页

MySQL由于某些原因宕机重启,此时Buffer Pool中修改的数据还没有及时的刷到磁盘中,就会导致数据丢失,无法保证事务的持久性。为了解决这个问题引入了redo log

日志文件由两部分组成:重做日志缓冲(redo log bufer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘,发生错误时,进行数据恢复使用。

redo log用到了WAL(Write-Ahead Logging)技术,这个技术的核心就在于修改记录前,一定要先写日志,并保证日志先落盘,才能算事务提交完成。有了redo log再修改数据时,InnoDB引擎会把更新记录先写在redo log中,在修改Buffer Pool中的数据,当提交事务时,调用fsync把redo log刷入磁盘。至于缓存中更新的数据文件何时刷入磁盘,则由后台线程异步处理

redo log 采用大小固定,循环写入的方式,当写满后,会重新从头开始循环写,类似一个环状。这样设计原因是 redo log 记录的是数据页上的修改,如果 Buffer Pool 中数据页已经刷到磁盘,这些记录就失效了,新日志会将这些失效的记录覆盖擦除。

注意:redo log 满了,在擦除之前,要确保这些要被擦除记录都已经刷到磁盘中了。在擦除旧记录释放新空间期间,不能再接收新的更新请求,此时 MySQL 性能会下降。因此高并发情况下,合理调整 redo log 大小很重要。

Undo Log

undo Log(回滚日志)是MySQL中的一种重要数据结构,用于实现事务的ACID特性中的"Atomicity"(原子性)和"Isolation"(隔离性)。

事务提交成功由redo log保证数据持久性,而事务可以进行回滚从而保证事务操作原子性则是通过undo log 来保证的。

undo log产生和销毁:Undo Log在事务开始前产生;事务在提交时,并不会立刻删除undo log,innodb会将该事务对应的undo log放入到删除列表中,后面会通过后台线程purge thread进行回收处理

  • 事务A执行update更新操作,在事务没有提交之前,会将旧版本数据备份到对应的undo buffer中,然后再由undo buffer持久化到磁盘中的undo log文件中, 之后才会对user进行更新操作,然后持久化到磁盘
  • 在事务A执行的过程中,事务B对User进行了查询

在Mysql里数据每次修改前,都首先会把修改之前的数据作为历史保存一份到undo log里面的,数据里面会记录操作该数据的事务ID,然后我们可以通过事务ID来对数据进行回滚。

可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

总结

redo log日志记录的是数据页的物理变化,服务宕机可用来同步数据,而undo log 不同,它主要记录的是逻辑日志,当事务回滚时,通过逆操作恢复原来的数据,比如我们删除一条数据的时候,就会在undo log日志文件中新增一条delete语句,如果发生回滚就执行逆操作。

redo log保证了事务的持久性,undo log保证了事务的原子性和一致性


相关实践学习
日志服务之数据清洗与入湖
本教程介绍如何使用日志服务接入NGINX模拟数据,通过数据加工对数据进行清洗并归档至OSS中进行存储。
相关文章
|
2月前
|
SQL 存储 关系型数据库
redo log 的执行流程?
redo log 的执行流程?
|
18天前
|
存储 关系型数据库 MySQL
|
18天前
|
存储 关系型数据库 MySQL
|
2月前
|
存储 SQL 关系型数据库
[MySQL]事务原理之redo log,undo log
[MySQL]事务原理之redo log,undo log
152 0
|
2月前
|
SQL 缓存 关系型数据库
MySQL的万字总结(缓存,索引,Explain,事务,redo日志等)
MySQL的万字总结(缓存,索引,Explain,事务,redo日志等)
100 0
|
2月前
|
数据库
redo log日志格式
redo log日志格式
|
2月前
|
存储 监控 关系型数据库
MySQL Redo Log解密:事务故事的幕后英雄
MySQL Redo Log解密:事务故事的幕后英雄
37 0
|
3天前
|
监控
查看服务器/IIS日志、log、访问信息基本方法
除了手动查看,你也可以使用日志分析工具,如Log Parser、AWStats等,这些工具可以帮助你更方便地分析日志数据。
4 1
|
11天前
|
Java 测试技术 Apache
《手把手教你》系列基础篇(八十六)-java+ selenium自动化测试-框架设计基础-Log4j实现日志输出(详解教程)
【7月更文挑战第4天】Apache Log4j 是一个广泛使用的 Java 日志框架,它允许开发者控制日志信息的输出目的地、格式和级别。Log4j 包含三个主要组件:Loggers(记录器)负责生成日志信息,Appenders(输出源)确定日志输出的位置(如控制台、文件、数据库等),而 Layouts(布局)则控制日志信息的格式。通过配置 Log4j,可以灵活地定制日志记录行为。
27 4
|
12天前
|
运维 Java Apache
Java中的日志框架:Log4j与SLF4J详解
Java中的日志框架:Log4j与SLF4J详解