redo log和undo log、事务

本文深入探讨了数据库中redolog和undolog的作用,redolog用于恢复未同步到磁盘的修改,undolog则用于事务回滚和MVCC。同时介绍了事务的隐式提交、保存点、隔离级别实现等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redo log和undo log、事务

redo log

如果系统突然崩溃,一些在缓存中的修改还没来的及同步到磁盘中,用redo log就可以恢复这些修改,Redo log就是记录这些修改的日志。这些对页面的修改有一些是原子操作,比如有些插入伴随着页面分裂和页的新建(悲观插入),此时这些分裂和修改必须一气呵成,这样的操作叫mini-transition,一条语句可能包含多个mini-transition,而一个又包含多个redo日志,这种原子性用一个特殊位来标记,在恢复时读到标志位才恢复之前的内容,否则放弃之前的日志。每次的redo日志也是存到buffer pool中,选择合适的时机刷新到磁盘,可以选择事务提交时同步到磁盘或写入缓存。

(LSN:记录的一个字段,一个redo日志对应的编号,一个页的LSN越大说明刚刚修改过)

undo log

为了事务回滚而记录的日志信息,undo日志有几种类型,插入数据、删除数据、更新数据都会产生不同的undo log,记录有一个roll_pointer的指针指向它的undo log,所有关于这条记录的undo log都连成一条链表,称为版本链,根据undo log的事务ID来判断是哪个事务中修改了该记录,事务回滚时找到对应事务ID的undo log恢复数据除此之外,undo log还可以用来维护MVCC(多版本并发控制)。

(mysql删除时实际上分两步,第一步是标记删除,如果事务提交再将其放入垃圾链表中)

事务

事务的隐式提交:一些DDL语言(create、drop、alter)、使用表的语句(带table的)、开启另一个事务等。。。

创建保存点:savepoint 保存点名

回滚到保存点:rollback to 保存点名

事务的使用:start transaction、commit、rollback

隔离级别的实现

Read uncommitted的实现:每次读时都读最新的那个版本,并发问题最严重

Read committed的实现:避免脏写,在每次读取数据时都生成一个readview,readview其中存有创建当前结构的事务ID,活跃事务ID,然后从记录开始读每个undo log,如果某个undo log刚好是事务的创建ID或不在readview的活跃事务列表中就可以读,这样就避免了脏读。

Repeatable read的实现:在事务第一次读的时候生成readview,然后读记录,这样就能保证读到的数据不可能不一样。

Serializable的实现:依赖mysql的锁

转载于:https://www.cnblogs.com/shizhuoping/p/11562879.html

<think>好的,我现在需要详细回答用户关于MySQL中redo logundo log的区别作用的问题。用户已经提供了一些站内引用,我需要结合这些引用以及之前回答中的内容来构建一个全面且准确的解释。 首先,我需要明确redo logundo log的基本概念,然后分析它们的不同点,包括功能、存储位置、生命周期、日志类型、恢复方向以及关联事务等方面。同时,用户提到的引用中有关于两阶段提交日志结构的内容,这些也需要整合到回答中,确保覆盖关键点。 接下来,我应该检查之前的回答是否已经涉及了这些日志类型。在之前的回答中,用户主要关注错误日志、二进制日志、慢查询日志通用查询日志,而redo logundo log属于事务日志,需要在此次回答中详细展开。 需要确保回答结构清晰,分点说明,使用用户要求的格式,如行内数学表达式用$...$,独立公式用$$...$$,并且正确引用提供的参考资料。同时,生成相关问题,帮助用户进一步理解。 另外,要注意引用标记的正确使用,例如引用[^1]、[^2]等,这些需要用户提供的引用对应起来。例如,用户提供的引用[1]提到redo logbinlog的区别,引用[4]涉及两阶段提交恢复机制,这些都需要在适当的位置引用。 最后,总结redo logundo log的区别作用,确保内容准确,语言简洁,符合用户要求的中文回答,并生成相关问题供用户参考。</think>### MySQL中redo logundo log的对比解析 --- #### 一、核心概念作用对比 1. **redo log(重做日志)** - **功能定位**:InnoDB存储引擎层日志,确保事务的**持久性**(Durability) - **核心作用**: - 记录物理层面的数据页修改(例如:$page\_no=5$的页中偏移量$offset=128$处更新为值$0x1A3F$)[^1][^4] - 用于崩溃恢复时**重放未写入数据文件的修改** - **写入机制**: - 采用**循环写入**模式(固定大小文件组) - 通过`innodb_flush_log_at_trx_commit`参数控制刷盘策略[^4] 2. **undo log(回滚日志)** - **功能定位**:实现事务的**原子性**(Atomicity)多版本并发控制(MVCC) - **核心作用**: - 记录事务修改前的数据镜像,支持事务回滚(`ROLLBACK`) - 为读操作提供一致性视图(通过`Read View`访问历史版本数据)[^2] - **存储形式**: - 以**逻辑日志**形式记录反向操作(例如:INSERT对应DELETE,UPDATE记录旧值) - 存储在特殊的undo表空间中(MySQL 8.0默认使用独立UNDO表空间) --- #### 二、关键差异分析 | **对比维度** | **redo log** | **undo log** | |--------------------|---------------------------------------|---------------------------------------| | **所属层级** | InnoDB存储引擎层实现[^4] | InnoDB存储引擎层实现[^4] | | **日志类型** | 物理日志(记录数据页修改) | 逻辑日志(记录反向操作语句) | | **主要目的** | 崩溃恢复时保证数据持久性 | 事务回滚MVCC支持 | | **生命周期** | 事务提交后仍可能保留(用于恢复) | 事务提交后随版本链清理逐渐删除 | | **写入触发条件** | 数据修改发生时立即记录 | 事务开启后首次数据修改时生成 | | **可见性** | 仅InnoDB内部使用 | 通过`SELECT ... FOR UPDATE`可间接访问| | **事务的关系** | 所有事务共享日志缓冲区 | 每个事务拥有独立的undo链 | --- #### 三、协作流程示例(以UPDATE为例) 1. **事务启动**:生成事务ID(trx_id)并分配undo log段 2. **修改数据前**: - 将原始数据拷贝到undo log(构建回滚段) - 生成`UNDO LOG RECORD`记录旧值[^4] 3. **执行数据修改**: - 在内存中更新数据页,生成`redo log record`写入log buffer - 若开启binlog,同时写入binlog cache(两阶段提交)[^4] 4. **事务提交**: - 将redo log buffer刷盘(`prepare`阶段) - binlog刷盘后,redo log标记为`commit`状态[^4] 5. **崩溃恢复**: - 检查binlog完整性,通过redo log重做未落盘的数据页修改 - 使用undo log回滚未提交的事务修改 --- #### 四、高级特性关联 1. **两阶段提交(2PC)** redo logbinlog通过两阶段提交保证跨存储引擎的事务一致性[^4]: ```mermaid graph LR A(事务提交) --> B(redo log prepare) B --> C(binlog写入) C --> D(redo log commit) ``` 2. **MVCC实现基础** 通过undo log构建版本链实现非锁定读: $$ \text{Read View} = [trx\_id_{min}, trx\_id_{max}, active\_trx\_list] $$ 根据事务ID选择可见的undo log版本 --- #### 五、配置管理要点 1. **redo log优化** - 设置合理的日志文件大小(`innodb_log_file_size`,建议4GB以上) - 调整刷盘策略(`innodb_flush_log_at_trx_commit=1`确保ACID) ```ini [mysqld] innodb_log_files_in_group=3 # 日志文件数量 innodb_log_file_size=4G # 单个文件大小 ``` 2. **undo log管理** - 控制undo表空间数量(MySQL 8.0+) - 设置自动清理阈值(`innodb_undo_log_truncate=ON`) ```sql ALTER UNDO TABLESPACE innodb_undo_001 SET INACTIVE; # 手动触发清理 ``` --- ### 相关问题 1. 如何通过redo log实现崩溃恢复的具体流程? 2. undo log在MVCC中如何支持一致性读? 3. 两阶段提交如何避免binlogredo log数据不一致? 4. 什么情况下需要调整redo log文件的大小?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值