Redo log,Undo log和binlog
-
所属层面: Redo Log 和 Undo Log 主要与 存储引擎 相关(特指 InnoDB),而 Binlog 是 MySQL 服务器 层面的日志。
-
记录内容: Redo Log 记录的是对数据页的物理修改("做了什么修改"),Undo Log 记录的是逻辑的回滚操作("怎么撤销修改"),Binlog 记录的是导致数据变化的逻辑事件("执行了什么操作")。
-
作用: Redo Log 主要用于崩溃恢复(Crash Recovery),保证已提交事务的持久性(Durability);Undo Log 主要用于事务回滚(Rollback)*和实现 **多版本并发控制(MVCC)**,保证事务的*原子性(Atomicity);Binlog 主要用于主从复制(Replication)*和*时间点恢复(Point-in-Time Recovery, PITR)。
-
写入时机: Redo Log 在事务进行中持续写入(遵从 Write-Ahead Logging 原则);Undo Log 在事务进行中生成和写入;Binlog 在事务提交时写入(非事务性存储引擎可能是语句执行完就写)。
下面我们分别详细解释它们的作用:
1. Redo Log (重做日志)
-
所属层面: InnoDB 存储引擎
-
记录内容: 物理日志。记录的是对数据页的物理修改,比如“将页 A 的偏移量 X 处的值从 Y 改为 Z”。
-
核心作用: 确保事务的持久性 (Durability) 和崩溃恢复 (Crash Recovery)。
-
工作原理 (Write-Ahead Logging, WAL):
-
InnoDB 在处理事务时,会将数据页加载到内存的 Buffer Pool 中进行修改。
-
为了提高性能,Buffer Pool 中的脏页(修改过但还没写回磁盘的数据页)不会立即同步到磁盘,而是会延迟写入。
-
但如果修改的数据在内存中,还没来得及写回磁盘就发生了数据库崩溃,那么这些已提交的事务修改就会丢失,这违反了事务的持久性要求。
-
为了解决这个问题,InnoDB 引入了 Redo Log。在事务提交之前,InnoDB 会先把该事务对数据页的修改以 Redo Log 的形式记录下来,并刷写到磁盘上的 Redo Log 文件中。这个过程称为 WAL (Write-Ahead Logging),即 先写日志,再写数据。
-
Redo Log 是顺序写入的,速度很快。
-
崩溃恢复时: 如果数据库发生崩溃,重启时 InnoDB 会检查 Redo Log。它会重放(replay)Redo Log 中记录的修改操作,将 Buffer Pool 中还没来得及写回磁盘的脏页重新应用到对应的数据页上,从而恢复到崩溃前的状态,保证所有已提交的事务都不会丢失。
-
-
特点: Redo Log 是循环写入的,通常由一组固定大小的文件组成(如 ib_logfile0, ib_logfile1 等)。当写到最后一个文件末尾时,会回到第一个文件开头继续写,覆盖之前的内容(前提是被覆盖的部分对应的脏页已经刷回磁盘)。
-
总结: Redo Log 就像一个临时的、快速记录的“草稿本”,在正式修改数据文件之前,先把修改的意图记下来。这样即使系统崩溃,“草稿本”还在,重启后可以照着“草稿本”把那些还没完成的修改重新做一遍,保证数据不丢。
2. Undo Log (回滚日志)
-
所属层面: InnoDB 存储引擎
-
记录内容: 逻辑日志。记录的是如何撤销(undo)一个操作。比如对于一条 INSERT 操作,Undo Log 会记录一个 DELETE 操作;对于一条 UPDATE 操作,Undo Log 会记录 UPDATE 前的旧值。
-
核心作用: 保证事务的原子性 (Atomicity) 和实现多版本并发控制 (MVCC)。
-
工作原理 (事务回滚和 MVCC):
-
事务回滚: 当一个事务需要回滚(无论是用户执行 ROLLBACK 语句,还是系统因错误自动回滚)时,InnoDB 会读取该事务对应的 Undo Log,并根据 Undo Log 中记录的信息将数据恢复到事务开始前的状态。这是保证事务原子性的关键。
-
MVCC: InnoDB 利用 Undo Log 来实现多版本并发控制。当一个事务修改数据时,它不会直接覆盖旧值,而是将旧值存入 Undo Log,然后在数据行中记录一个指向 Undo Log 中旧版本的指针。这样,正在读取该数据的其他事务(在合适的隔离级别下,如 Repeatable Read)就可以通过这个指针访问到修改前的旧版本数据,而不会看到当前事务尚未提交的修改。这允许多个事务在同一时间读取和写入数据而不会相互阻塞,提高了并发性。
-
-
特点: Undo Log 是与事务相关的。一个事务开始时,会创建对应的 Undo Log 段。事务提交后,如果这个事务的修改不再需要用于 MVCC(即没有其他活动事务需要看到这个旧版本的数据),对应的 Undo Log 空间会被逐步释放。
-
总结: Undo Log 就像一个详细的“撤销步骤说明书”。它记录了你每一步操作的反向操作。如果事务失败或需要撤销,就可以按照这个说明书一步步回到最初的状态。同时,它也留下了数据的“历史版本”,供其他需要旧数据的事务查看。
3. Binlog (二进制日志)
-
所属层面: MySQL 服务器
-
记录内容: 逻辑日志。记录的是数据库执行的更改数据的逻辑事件,比如执行了哪个 SQL 语句 (Statement-Based Logging) 或者哪些行发生了变化 (Row-Based Logging)。它记录的是“做了什么操作”,而不是“操作如何改变了物理页面”。
-
核心作用: 主从复制 (Replication) 和时间点恢复 (Point-in-Time Recovery)。
-
工作原理:
-
当 MySQL 服务器执行一个改变数据的语句(如 INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE 等)时,如果 Binlog 功能开启,服务器就会将这个事件记录到 Binlog 文件中。
-
Binlog 的写入是在事务提交之后才发生的(对于非事务性表,可能是语句执行后)。这保证了 Binlog 中记录的都是已经成功提交并持久化的事务。
-
主从复制: 在主从复制架构中,从库(Replica)会连接到主库(Source),读取主库的 Binlog,然后在自己的数据库上重放这些 Binlog 事件,从而保持与主库的数据同步。
-
时间点恢复 (PITR): Binlog 记录了数据库在某个时间点之后发生的所有数据变更事件。通过结合一个完整的备份(通常是某个时间点的快照)和该时间点之后的 Binlog 文件,可以将数据库恢复到备份之后到任意指定时间点或指定事务结束时的状态。
-
-
特点: Binlog 是顺序写入的,由一系列编号递增的文件组成(如 mysql-bin.000001, mysql-bin.000002 等)。新的事件总是追加到当前 Binlog 文件的末尾。当当前文件达到一定大小时,会切换到下一个文件继续写。Binlog 文件通常需要手动清理或者配置自动清理策略。
-
总结: Binlog 就像一个数据库的“操作历史记录本”,它记录了所有导致数据变化的事件。这本历史书可以被复制到其他地方(复制),也可以用来“回放”历史,将数据库恢复到过去的某个状态(PITR)。
简要对比表格:
特性 | Redo Log (InnoDB) | Undo Log (InnoDB) | Binlog (MySQL Server) |
---|---|---|---|
所属层面 | 存储引擎 (InnoDB) | 存储引擎 (InnoDB) | 服务器 |
记录内容 | 物理修改 (怎么改了哪个数据块) | 逻辑回滚操作 (怎么撤销修改) | 逻辑事件 (执行了什么 SQL 或行变更) |
主要作用 | 保证持久性、崩溃恢复 | 保证原子性、事务回滚、MVCC | 主从复制、时间点恢复 |
写入时机 | 事务进行中,提交前先写 (WAL) | 事务进行中生成和写入 | 事务提交时或语句执行后 |
格式 | 物理页面修改记录 | 逻辑撤销记录 | 语句或行变更记录 |
生命周期 | 循环使用,覆盖旧内容 (当脏页写回后) | 事务提交后,MVCC 不再需要时清除 | 顺序写新文件,旧文件按策略清除或手动清除 |
理解这三个日志的区别和作用,对于理解 MySQL 如何保证事务的 ACID 特性,以及如何进行数据恢复和高可用架构(如主从复制)是非常重要的。