图解MySQL【日志】——Undo Log

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 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 页都是靠这个机制保证持久化的。


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
8天前
|
监控 Java 应用服务中间件
Tomcat log日志解析
理解和解析Tomcat日志文件对于诊断和解决Web应用中的问题至关重要。通过分析 `catalina.out`、`localhost.log`、`localhost_access_log.*.txt`、`manager.log`和 `host-manager.log`等日志文件,可以快速定位和解决问题,确保Tomcat服务器的稳定运行。掌握这些日志解析技巧,可以显著提高运维和开发效率。
66 13
|
11天前
|
存储 SQL 关系型数据库
mysql的undo log、redo log、bin log、buffer pool
MySQL的undo log、redo log、bin log和buffer pool是确保数据库高效、安全和可靠运行的关键组件。理解这些组件的工作原理和作用,对于优化数据库性能和保障数据安全具有重要意义。通过适当的配置和优化,可以显著提升MySQL的运行效率和数据可靠性。
23 4
|
10天前
|
SQL 存储 关系型数据库
简单聊聊MySQL的三大日志(Redo Log、Binlog和Undo Log)各有什么区别
在MySQL数据库管理中,理解Redo Log(重做日志)、Binlog(二进制日志)和Undo Log(回滚日志)至关重要。Redo Log确保数据持久性和崩溃恢复;Binlog用于主从复制和数据恢复,记录逻辑操作;Undo Log支持事务的原子性和隔离性,实现回滚与MVCC。三者协同工作,保障事务ACID特性。文章还详细解析了日志写入流程及可能的异常情况,帮助深入理解数据库日志机制。
|
4天前
|
关系型数据库 MySQL 数据库连接
docker拉取MySQL后数据库连接失败解决方案
通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
105 82
|
2月前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决
|
7天前
|
消息中间件 缓存 NoSQL
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
|
1月前
|
关系型数据库 MySQL 数据库
Docker Compose V2 安装常用数据库MySQL+Mongo
以上内容涵盖了使用 Docker Compose 安装和管理 MySQL 和 MongoDB 的详细步骤,希望对您有所帮助。
194 42
|
12天前
|
SQL 关系型数据库 MySQL
MySQL生产环境迁移至YashanDB数据库深度体验
这篇文章是作者将 MySQL 生产环境迁移至 YashanDB 数据库的深度体验。介绍了 YashanDB 迁移平台 YMP 的产品相关信息、安装步骤、迁移中遇到的各种兼容问题及解决方案,最后总结了迁移体验,包括工具部署和操作特点,也指出功能有优化空间及暂不支持的部分,期待其不断优化。
|
1月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
150 25
|
23天前
|
监控 关系型数据库 MySQL
云数据库:从零到一,构建高可用MySQL集群
在互联网时代,数据成为企业核心资产,传统单机数据库难以满足高并发、高可用需求。云数据库通过弹性扩展、分布式架构等优势解决了这些问题,但也面临数据安全和性能优化挑战。本文介绍了如何从零开始构建高可用MySQL集群,涵盖选择云服务提供商、创建实例、配置高可用架构、数据备份恢复及性能优化等内容,并通过电商平台案例展示了具体应用。