【MVCC、Undolog、Redolog】

目录

前言

一、MVCC是什么?

1.MVCC实现三个要素

二、Undolog

三、Redolog

总结



前言

MVCC与Undolog、Redolog这几种曾让我很困惑,最近看了好多文章,结合自己理解,记录下来,好记性不如烂笔头


提示:以下是本篇文章正文内容,下面案例可供参考

一、MVCC是什么?

MVCC(Multiversion Concurrency Control),即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。

个人理解:当前事务读取时,不必加锁,根据规则读取可以显示的版本记录,也就是快照读

1.MVCC实现三个要素

  隐藏字段、undolog、readvidw

- 隐藏字段

每一行数据中有创建者自己设置的字段,还有mysql自动给增加的隐藏字段,主要是DATA_TRX_ID(事务id)和DATA_ROLL_PTR(旧版本undolog指针)

idnameageDATA_TRX_IDDATA_ROLL_PTR
1小明1830x123fff
2小刚2020x434fff

DATA_TRX_ID:指的是当前记录的事务id

DATA_ROLL_PTR:指向undolog的上一版本的地址

- undolog 

undolog会记录事务前老版本数据,然后行记录中回滚指针会指向老版本位置,如此形成一条版本链。因此可以利用undo log实现回滚,保证原子性,同时用于实现MVCC版本链。

个人理解:数据操作时,会将之前记录存入到undolog里,然后用指针进行连接起来的一个链表,这样可以保证事务失败时可以进行回滚,保证事务的原子性,还有可以通过事务id根据算法找到当前可以读的版本,也就是快照读

比如:数据更新,将age从18变成20,旧记录就会存入undolog,存储的地址为0xffff,事务id会新增,多个版本会以链表进行存入undolog日志中。

 - readview

前面提到的判断某一个快照读能读到哪些版本,按照某种算法,这个readView就是该算法的关键。有以下几个变量。

  • m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表(未提交的事务)。

  • min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。

  • max_trx_id:表示生成ReadView时系统中应该分配给下一个事务的id值。

    小贴士: 注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三个事务,之后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,min_trx_id的值就是1,max_trx_id的值就是4。

  • creator_trx_id:表示生成该ReadView的事务的事务id

具体算法:

               

 参考连接:MVCC ReadView介绍 - IUNI_JM - 博客园

二、Undolog

详见上面

三、Redolog

MySQL作为一个存储系统,为了保证数据的可靠性,最终得落盘。但是,又为了数据写入的速度,需要引入基于内存的"缓冲池"。既然数据是先缓存在缓冲池中,然后再以某种方式刷新到磁盘,那么就存在因宕机导致的缓冲池中的数据丢失,为了解决这种情况下的数据丢失问题,引入了redo log。保证了数据的持久性

redolog的大小是固定的,在mysql中可以通过修改配置参数innodb_log_files_in_group和innodb_log_file_size配置日志文件数量和每个日志文件大小,redolog采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。


write pos->checkpoint之间的部分是redo log空着的部分,用于记录新的记录,

checkpoint->write pos之间是redo log待落盘的数据修改记录

参考连接:mysql日志系统之redo log和bin log - 简书


总结

以上是我对这三者的一个学习的记录,多写一点可能更熟悉一点。

### Undo Log、Redo Log MVCC 的概念及关系 #### 1. **Undo Log 的定义与作用** Undo Log 是一种逻辑日志,主要用于记录数据被修改前的状态。它的核心目的是支持事务的回滚操作以及实现 MVCC 中的多版本控制[^4]。 - 当删除一条记录时,Undo Log 会记录一条对应的插入记录;当插入一条记录时,则记录一条对应的删除记录;对于更新操作,Undo Log 记录的是反向的操作内容。 - 在事务未提交之前,如果发生异常或者用户主动调用了 `ROLLBACK`,则可以通过 Undo Log 恢复到原始状态。 Undo Log 对于 MVCC 至关重要,因为它是生成历史版本的基础。每当有新的写入或更改发生时,旧版本会被保留下来作为快照供其他只读事务使用[^4]。 #### 2. **Redo Log 的定义与作用** Redo Log 属于物理日志范畴,其主要职责在于保障持久化崩溃恢复能力[^3]。 - Redo Log 文件具有固定大小,并且采用循环写入模式。这意味着一旦达到文件末尾,MySQL 将返回起始位置重新开始记录新日志。 - 它的作用是在实例意外终止(如断电等情况)之后帮助重做尚未完成写盘的数据变更,从而确保已经成功提交的事务不会因系统故障丢失任何信息。 两阶段提交机制进一步加强了 Redo Log Binlog 协同工作的可靠性[^1]。简单来说,在正式确认 Commit 前先经历 Prepare 阶段并将相关信息记入 Redo Log ,随后才依次处理 Binlog 写入其他后续步骤直至最终完成整个流程[^1]。 #### 3. **MVCC 的角色定位** MVCC 多版本并发控制主要是通过组合运用 Undo Log 实现高效的读写分离方案[^2]。具体表现为: - 不同时间点发起的不同事务可以根据各自建立之初所形成的 Read View 查看相应的数据副本而非实时变动后的最新结果集[^2]。 - 这样既提高了系统的整体吞吐量又减少了传统锁机制带来的阻塞风险。 综上所述,尽管三者都服务于提升数据库性能这一共同目标却各有侧重——其中 Undo Log 关注过去时刻事物状态保存以便必要时候还原;Redo Log 注重未来可能出现的各种不确定性准备充分预案以维持数据完整性;而 MVCC 则巧妙借助前者构建起了灵活的时间轴视角下的查询体验优化框架。 ```python # 示例代码展示如何模拟简单的日志记录行为 class TransactionLog: def __init__(self): self.redo_logs = [] self.undo_logs = [] def add_redo(self, action): self.redo_logs.append(action) def add_undo(self, reverse_action): self.undo_logs.append(reverse_action) transaction = TransactionLog() transaction.add_redo("Insert record A") transaction.add_undo("Delete record A") print("Redo Logs:", transaction.redo_logs) print("Undo Logs:", transaction.undo_logs) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值