MySQL中redo log和undo log的核心知识点如下:
Redo Log(重做日志)
1. 核心作用
- 保证事务持久性:通过记录数据页的物理修改,确保系统崩溃后已提交事务的数据不丢失。
- 减少随机IO:将随机写入转换为顺序追加写入,提升性能。数据修改先写入内存中的buffer pool,再通过redo log异步刷盘。
2. 组成结构
- Redo Log Buffer:内存区域,默认16MB,通过innodb_log_buffer_size配置。
- Redo Log File:磁盘文件(如ib_logfile0、ib_logfile1),默认每组2个,单个文件大小由innodb_log_file_size控制(默认48MB)。
3. 写入流程
- 修改内存中的数据页,生成脏页。
- 生成redo log并写入redo log buffer,记录“页偏移量+修改值”。
- 事务提交时,根据刷盘策略将redo log buffer刷新到磁盘文件。
- 后台线程定期将脏页刷回磁盘。
4. 刷盘策略
- 0:每秒刷新一次,可能丢失1秒数据(性能高,不保证持久性)。
- 1(默认):事务提交时同步刷盘,保证持久性但性能最低。
- 2:提交时写入操作系统内核缓冲区,刷盘时机由OS决定(平衡性能与安全性)。
Undo Log(回滚日志)
1. 核心作用
- 保证事务原子性:事务失败时回滚未提交的修改。
- 支持MVCC:通过版本链实现快照读,避免锁冲突。
2. 记录内容
- INSERT操作:记录主键值,回滚时直接删除对应行。
- UPDATE/DELETE操作:记录修改前的旧值,回滚时恢复旧数据。
3. 存储结构
- 回滚段(Rollback Segment):MySQL 5.5+支持128个回滚段,每个包含1024个undo log segment。
- 版本链:事务提交后,undo log不立即删除,而是通过DB_ROLL_PTR指针形成链表,由purge线程清理。
4. 生命周期
- Insert Undo Log:事务提交后直接删除(仅对当前事务可见)。
- Update Undo Log:需保留以支持MVCC,提交后加入版本链,等待purge线程最终删除。
Redo Log与Undo Log的协同
- 崩溃恢复:
若事务未提交,根据undo log回滚修改。
若事务已提交但未刷盘,通过redo log重做修改。
- 两阶段提交:
Prepare阶段:redo log标记为prepare状态。
Commit阶段:写入binlog后,redo log标记为commit。确保redo log与binlog逻辑一致,避免数据不一致。
扩展:Binlog(二进制日志)
- 作用:记录所有修改数据的SQL语句,用于主从复制和数据恢复。
- 与Redo Log区别:
层级:redo log是InnoDB引擎层物理日志,binlog是MySQL服务层逻辑日志。
内容:redo log记录页修改,binlog记录SQL逻辑。
写入时机:redo log在事务执行中写入,binlog在事务提交时写入。