图解MySQL【日志】——Undo Log

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: Undo Log(回滚日志)是 MySQL 中用于实现事务原子性和一致性的关键机制。在默认的自动提交模式下,MySQL 隐式开启事务,每条增删改语句都会记录到 Undo Log 中。其主要作用包括:

 Undo Log(回滚日志)

为什么需要 Undo Log?

1. MySQL 的隐式开启事务

自动提交(autocommit = 1)

  • 默认的自动提交模式下(autocommit = 1),MySQL 在执行每一条增删改语句时会隐式地开启一个独立的事务,并在执行完成后自动提交。

目的

  • 原子性:保证每个“增删改”操作的原子性。
  • 提高便携性:对于简单的操作,开发者不需要每次都先 begincommit 来实现事务。

2. 事务回滚——保证事务的原子性和一致性

  • 保证原子性:引入 Undo Log 的主要原因是为了实现事务的回滚,以确保事务的原子性。有了回滚的选项后,无论是事务提交前发生崩溃、事务执行过程出错,都可以通过回滚操作来确保原子性。
  • 保证一致性
  • 事务执行过程中出现异常,通过回滚来防止部分更新,确保一致性。
  • 配合 MVCC,确保读取数据的一致性:
  • 可重复读隔离级别:通过 Undo Log 获取数据的历史版本来确保事务执行期间看到数据的一致。
  • 快照读:事务读取数据时,通过 Undo Log 获取数据的历史版本,确保读操作不会因为其他事务的修改而破坏一致性。

3. 为 MVCC 提供数据的历史版本——(间接)保证事务的隔离性

  • 记录数据历史版本,使得 MySQL 可以提供事务的快照
  • 当一个数据进行更改时,先将原数据记录到 Unodo Log 中,而不是直接修改数据。
  • 这样,在事务执行过程中,即使其他事务已经对该数据进行了更改,当前事务依然可以读取到事务开始时的数据版本——可重复读隔离级别。

实现事务回滚——保证事务的原子性(A)

1. 核心原理

  • Undo Log 是一种用于撤销回退的日志,在事务未提交之前,MySQL 会记录更新的数据到 Undo Log 日志文件里,当事务回滚时,就可以利用 Undo Log 进行回滚。

2. 过程如下图

image.gif 编辑


3. 具体实现

Undo Log 是由 InnoDB 提供,当 InnoDB 引擎对一条记录进行操作(插入、删除、更新)时,会按操作类型在 Undo Log 中分别进行不同的记录。

  • insert 回滚:记录这条记录的主键值,回滚时只需要将该主键值对应的记录删除
  • delete 回滚:把对应的记录内容都记下来,回滚时再将这些内容组成记录并插入表中。
  • delete
  • 具体过程:不会立即删除,将要删除的记录标记为 delete flag,表示已删除,最终的删除操作是由 purge 线程,择机扫描表中已标记为删除的记录,并进行真正的物理删除。
  • 这样实现的目的
  • 性能优化delete flag 可以避免频繁的磁盘 I/O 操作,提高系统响应速度。
  • 避免数据丢失:防止误删或操作不当,让系统管理员更灵活地恢复数据或查看删除历史。
  • 并发问题:多个操作同时进行时,频繁地立即响应删除操作(更新索引、调整磁盘存储空间、处理事务锁定、日志记录等)会导致 MySQL 负载严重。
  • 缺点:已被标记为删除但未清理的数据,会占用内存空间,只能等到 purge 线程延迟清理后,才能释放空间。
  • update 回滚:将更新的列的旧值记录下来,回滚时将新值改为旧值。
  • update:取决于该列是否为主键列。
  • 非主键列:在 Undo Log 中直接反向记录如何 update 的,即 update 操作直接进行。
  • 主键列:分两步执行,先删除该行,再插入一行新的数据,主键值是更新后的值,其他列保持不变。
  • 目的:
  • 主键值决定了数据行的位置:InnoDB 是根据主键值来组织存储的,每行数据存储在聚集索引中,如果直接更新主键,原来数据所在的位置就会发生改变。故要删除原行,插入只有主键列为新值的记录。
  • 索引更新:在 InnoDB 中,聚集索引的结构就是数据本身,更新了主键列,相当于改变了数据行在内存中和磁盘上的存储位置,因此索引必须重新调整,以便与新的主键值保持一致。
  • 非聚集索引:当然除了主键索引会直接受影响,其他非聚集索引因为存储的是主键值的引用(存储主键值 + 指向数据行的“行 ID”),因此也必须随主键值而更新。
  • 例子:假设你有一个按 user_id 升序排列的表,当更新主键时,行的位置会发生变化,新的值 3 可能会导致数据行需要移动到别的位置,这样原有的主键索引条目就不能再指向正确的位置。
  • Undo Log 回滚记录:为了保证事务的可回滚性,InnoDB 会在 Undo Log 中分别记录这两步操作(删除原记录,插入只有主键列为新值的记录)的反向操作,从而确保即使事务失败,也能恢复原来的状态。

配合 ReadView 实现 MVCC(多版本并发控制)

1. 版本链

一条记录的每一次更新操作产生的 Undo Log 格式都有一个 roll_pointer 回滚指针和一个 trx_id 事务 id:

  • trx_id事务 id,通过 trx_id确定记录是由哪个事务修改的,并在回滚时清理特定事务产生的修改,保证事务的原子性与一致性。
  • roll_pointer回滚指针指向该数据的前一个版本,通过多个 roll_pointer 指针可以串成一个链表,表示从最初的数据一直到最新的数据版本,该链表成为版本链


  • image.gif 编辑

2. Undo Log 与隔离级别

读未提交(READ UNCOMMITTED)

  • 因为可以脏读(读取未提交的数据,事务回滚后数据消失,导致数据不一致性),Undo Log 几乎无作用。

读已提交(READ COMMITTED)

  • 提供历史版本数据,支持快照读(Snapshot Read)。
  • 事务 A 提交前,事务 B 依然可以读取 Undo Log 里的旧数据,避免脏读。
  • 问题:不可重复读(Non-Repeatable Read),即同一事务内对相同数据进行两次读取,可能得到不同的值

可重复读(REPEATABLE READ)

  • 提供当前事务开始时的数据快照,以保证事务在提交前都能读取到一致的版本
  • 即使其他事务提交了新事务,当前事务仍读取 Undo Log 里的旧数据,避免不可重复读。

串行化(SERIALIZABLE)

  • 特点:所有事务串行执行,事务之间完全隔离,使用行级锁避免任何并发修改。
  • 基本不依赖 Undo Log,因为事务串行执行,不需要 MVCC 提供历史版本数据。
  • 问题:性能较低。

3. 通过 ReadView + Undo Log 实现 MVCC(多版本并发控制)

  • 控制并发事务访问同一个记录时的行为,称为多版本并发控制(Multi-Version Concurrency Control)。
  • 【读已提交】和【可重复读】隔离级别是通过【事务的 ReadView 中的字段】和【记录中的两个隐藏列(trx_idroll_pointer)】的比对,如果该记录版本不满足可见行,就会顺着 Undo Log 的版本链依次继续比对,直到满足其可见性为止。

Undo Log 的持久化过程

1. Undo Log 和数据页的刷盘策略一致,且都需要 Redo Log 保证持久化。

2. Buffer Pool 中有 Undo 页,对 Undo 页的修改会记录到 Redo Log。依靠 Redo Log 刷盘,数据页和 Undo 页都是靠这个机制保证持久化的。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
19天前
|
SQL 运维 关系型数据库
深入探讨MySQL的二进制日志(binlog)选项
总结而言,对MySQL binlogs深度理解并妥善配置对数据库运维管理至关重要;它不仅关系到系统性能优化也是实现高可靠性架构设计必须考虑因素之一。通过精心规划与周密部署可以使得该机能充分发挥作用而避免潜在风险带来影响。
54 6
|
5月前
|
监控 容灾 算法
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
本文探讨了如何高效、经济且可靠地将海外应用与基础设施日志统一采集至阿里云日志服务(SLS),解决全球化业务扩展中的关键挑战。重点介绍了高性能日志采集Agent(iLogtail/LoongCollector)在海外场景的应用,推荐使用LoongCollector以获得更优的稳定性和网络容错能力。同时分析了多种网络接入方案,包括公网直连、全球加速优化、阿里云内网及专线/CEN/VPN接入等,并提供了成本优化策略和多目标发送配置指导,帮助企业构建稳定、低成本、高可用的全球日志系统。
629 54
|
5月前
|
SQL 监控 关系型数据库
MySQL日志分析:binlog、redolog、undolog三大日志的深度探讨。
数据库管理其实和写小说一样,需要规划,需要修订,也需要有能力回滚。理解这些日志的作用与优化,就像把握写作工具的使用与运用,为我们的数据库保驾护航。
213 23
|
6月前
|
SQL 运维 关系型数据库
MySQL Binlog 日志查看方法及查看内容解析
本文介绍了 MySQL 的 Binlog(二进制日志)功能及其使用方法。Binlog 记录了数据库的所有数据变更操作,如 INSERT、UPDATE 和 DELETE,对数据恢复、主从复制和审计至关重要。文章详细说明了如何开启 Binlog 功能、查看当前日志文件及内容,并解析了常见的事件类型,包括 Format_desc、Query、Table_map、Write_rows、Update_rows 和 Delete_rows 等,帮助用户掌握数据库变化历史,提升维护和排障能力。
|
7月前
|
监控 Java 应用服务中间件
Tomcat log日志解析
理解和解析Tomcat日志文件对于诊断和解决Web应用中的问题至关重要。通过分析 `catalina.out`、`localhost.log`、`localhost_access_log.*.txt`、`manager.log`和 `host-manager.log`等日志文件,可以快速定位和解决问题,确保Tomcat服务器的稳定运行。掌握这些日志解析技巧,可以显著提高运维和开发效率。
548 13
|
7月前
|
SQL 存储 关系型数据库
简单聊聊MySQL的三大日志(Redo Log、Binlog和Undo Log)各有什么区别
在MySQL数据库管理中,理解Redo Log(重做日志)、Binlog(二进制日志)和Undo Log(回滚日志)至关重要。Redo Log确保数据持久性和崩溃恢复;Binlog用于主从复制和数据恢复,记录逻辑操作;Undo Log支持事务的原子性和隔离性,实现回滚与MVCC。三者协同工作,保障事务ACID特性。文章还详细解析了日志写入流程及可能的异常情况,帮助深入理解数据库日志机制。
855 0
|
11月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
2981 31
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
10月前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
262 9
|
8月前
|
存储 SQL 关系型数据库
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log、原理、写入过程;binlog与redolog区别、update语句的执行流程、两阶段提交、主从复制、三种日志的使用场景;查询日志、慢查询日志、错误日志等其他几类日志
639 35
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log

推荐镜像

更多