当 MySQL 执行一条插入(INSERT)SQL 语句时,redo log(重做日志)记录的是物理层面的页修改,而不是 SQL 语句本身。具体来说:
1. redo log 记录的内容
redo log 主要记录以下信息:
- 被修改的数据页的物理变化(页号、偏移量、修改后的值)
- 事务的标识信息(事务ID等)
- LSN(Log Sequence Number)日志序列号
- 页的Before/After Image(在某些情况下)
对于一条 INSERT 语句,redo log 会记录:
- 数据页中新增行记录的物理变化
- 相关索引页的更新(如果有索引)
- undo log 页的修改(因为插入操作也需要记录 undo log 以便回滚)
2. redo log 的特点
- 物理日志:记录的是页面的物理修改,而不是逻辑操作
- 顺序写入:追加写入方式,磁盘顺序I/O,性能高
- 固定大小:循环写入,空间会被重复利用
- 崩溃恢复:保证已提交事务的持久性(Durability)
- WAL(Write-Ahead Logging):先写日志,再写数据页
3. 与 binlog 的区别
特性 | redo log | binlog |
---|---|---|
作用 | InnoDB 引擎层,保证崩溃恢复 | 服务器层,用于主从复制和数据恢复 |
记录内容 | 物理日志,记录页的修改 | 逻辑日志,记录SQL语句或行变更 |
写入时机 | 事务执行过程中不断写入 | 事务提交时一次性写入 |
日志大小 | 固定大小,循环写入 | 追加写入,不会覆盖 |
实现层面 | InnoDB 存储引擎实现 | MySQL Server 层实现 |
4. 插入语句的完整日志流程
- 事务开始
- 在内存中修改缓冲池(Buffer Pool)的数据页
- 记录 redo log 到 redo log buffer(此时未持久化)
- 记录 undo log(用于回滚)
- 事务提交时:
- redo log buffer 刷盘(fsync)
- 生成 binlog 并写入磁盘
- 提交标记写入 redo log
5. 为什么需要 redo log
- 保证持久性:即使系统崩溃,已提交事务的数据不会丢失
- 提高性能:将随机I/O(数据页修改)转换为顺序I/O(redo log写入)
- 实现崩溃恢复:MySQL重启时可以通过redo log重做已提交但未写入数据文件的修改
redo log 是 InnoDB 实现事务ACID特性中持久性(Durability)的关键组件。
THE END