tonglin0325的个人主页

MySQL学习笔记——undo log和redo log

MySQL的架构可以分成连接层,Server层和存储引擎层。

undo log
 和 redo log 是 MySQL InnoDB 存储引擎管理的数据日志类型,它们主要用于支持事务的 ACID 特性,即原子性、一致性、隔离性和持久性。

1.Undo Log(回滚日志)#

undo log 用于支持事务的原子性(Atomicity)隔离性(Isolation)。它在事务发生更改之前记录数据的原始状态,以便在事务回滚时能够将数据恢复到其原始状态。

undo log工作原理

  • 当一个事务对数据库中的数据进行修改(如 INSERTUPDATEDELETE 操作)时,InnoDB 会先将原始数据的副本写入 undo log
  • 如果事务需要回滚(无论是由于用户请求还是由于系统错误),InnoDB 使用 undo log 将更改撤销,使数据恢复到事务开始之前的状态。
  • undo log 也用于实现 一致性非锁定读(Consistent Non-Locking Reads)一致性非锁定读 是 MVCC 的核心特性之一。这意味着在事务的隔离级别为 REPEATABLE READREAD COMMITTED 时,可以提供一致的读取视图。它允许事务在读取数据时不加锁,从而避免阻塞其他事务。这种机制依赖于 undo logReadView,确保在高并发的情况下提供一致的读取视图。

undo log存储位置

  • undo log 存储在专用的 回滚段(rollback segment) 中,通常位于与数据文件相同的表空间内。

undo log主要用于事务回滚MVCC(多并发版本控制)

MVCC工作原理:

  • 可重复读(REPEATABLE READ)隔离级别:事务在开始时创建一个ReadView,并在整个事务期间使用这个ReadView,确保即使有其他事务提交了更改,当前事务的查询结果也保持一致。这样就保证了事务内的多次读取是可重复的。
  • 读已提交(READ COMMITTED)隔离级别下:ReadView是在每次执行查询时生成的,因此一个事务内的不同查询可能看到其他事务已经提交的更改。这样可以保证读取到的是其他事务已提交的数据,但无法保证事务内的多次读取结果一致。当事务执行读取操作时,ReadView 会判断数据的每个版本的可见性,这主要取决于版本的 事务 IDtrx_id

2.Redo Log(重做日志)#

redo log 用于支持事务的持久性(Durability)。它记录了已提交的事务对数据库进行的更改,这样在系统崩溃后可以通过redo log来恢复数据。

在redo log记录完成后,事务才算完成。后续,InnoDB 引擎会在适当的时候,由后台线程将缓存在 Buffer Pool 的脏页刷新到磁盘里,这就是 WAL (Write-Ahead Logging)技术

工作原理:

  • 在事务提交之前,所有的更改都会被写入 redo log 的日志缓冲区(redo log buffer)。
  • 当事务提交时,redo log 缓冲区会刷新到磁盘上的 redo log 文件。
  • 如果数据库崩溃,在重启时,InnoDB 可以使用 redo log 来重新应用(重做)日志中的所有更改,以确保所有已提交的事务持久化到数据库中。

存储位置:

  • redo log 存储在专用的日志文件中,InnoDB存储引擎有一个redo log group,由2个文件组成(通常为 ib_logfile0ib_logfile1)中,这些文件位于 InnoDB 的日志目录中。
  • 重做日志文件组是以**循环写**的方式工作的,从头开始写,写到末尾就又回到开头,相当于一个环形。所以 InnoDB 存储引擎会先写 ib_logfile0 文件,当 ib_logfile0 文件被写满的时候,会切换至 ib_logfile1 文件,当 ib_logfile1 文件也被写满时,会切换回 ib_logfile0 文件。

参考:MySQL 日志:undo log、redo log、binlog 有什么用?

3.两阶段提交(Two-Phase Commit, 2PC)#

在 MySQL 中,事务的操作首先写入到 redo log(InnoDB 的物理日志)中,用于崩溃恢复;同时,如果 MySQL 服务器配置了 binlog(二进制日志),事务的变化也需要记录到 binlog 中,作为逻辑日志,用于主从复制和增量备份。

为了确保这两个日志之间的一致性(即要么都成功,要么都失败),MySQL 使用了两阶段提交。如果没有这种机制,在事务提交过程中如果崩溃,可能会出现 redo log 和 binlog 之间的不一致,从而导致数据不一致的情况。