mysql多版本控制-MVCC

一、定义

多版本控制: 指的是一种提高并发的技术。最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。在内部实现中,与Postgres在数据行上实现多版本不同,InnoDB是在undolog中实现的,通过undolog可以找回数据的历史版本。找回的数据历史版本可以提供给用户读(按照隔离级别的定义,有些读请求只能看到比较老的数据版本),也可以在回滚的时候覆盖数据页上的数据。在InnoDB内部中,会记录一个全局的活跃读写事务数组,其主要用来判断事务的可见性。

二、数据库多版本读场景

session 1session 2
select a from test; return a = 10 
start transaction; 
update test set a = 20; 
 start transaction;
 select a from test; return ?
commit; 
 select a from test; return ?

我们看下上面这个数据库日常操作的例子。

  • session 1修改了一条记录,没有提交;与此同时,session 2 来查询这条记录,这时候返回记录应该是多少呢?
  • session 1 提交之后 session 2 查询出来的又应该是多少呢?

由于MySQL支持多种隔离级别,这个问题是需要看session2的事务隔离级别的,情况如下:

  • 隔离级别为 READ-UNCOMMITTED 情况下: 
    session 1 commit前后 session 2 去查看都会看到的是修改后的结果 a = 20
  • 隔离级别为 READ-COMMITTED 情况下: 
    session 1 commit 前查看到的还是 a =10 , commit之后看到的是 a = 20
  • 隔离级别为 REPEATABLE-READ, SERIALIZABLE 情况下: 
    session 1 commit前后 session 2 去查看都会看到的是修改后的结果 a = 10

其实不管隔离级别,我们也抛开数据库中的ACID,我们思考一个问题:众所周知,InnoDB的数据都是存储在B-tree里面的,修改后的数据到底要不要存储在实际的B-tree叶子节点,session2是怎么做到查询出来的结果还是10,而不是20列?

三、MVCC实现原理

上述现象在数据库中大家经常看到,但是数据库到底是怎么实现的,深究的人就不多了。 
其实原理很简单,数据库就是通过UNDO和MVCC来实现的。

通过DB_ROLL_PT 回溯查找数据历史版本

  • 首先InnoDB每一行数据还有一个DB_ROLL_PT的回滚指针,用于指向该行修改前的上一个历史版本 

    当插入的是一条新数据时,记录上对应的回滚段指针为NULL


更新记录时,原记录将被放入到undo表空间中,并通过DB_ROLL_PT指向该记录。session2查询返回的未修改数据就是从这个undo中返回的。MySQL就是根据记录上的回滚段指针及事务ID判断记录是否可见,如果不可见继续按照DB_ROLL_PT继续回溯查找。

通过read view判断行记录是否可见

Read View的数据结构,它有三个部分:

  • 当前活跃的事务列表
  • Tmin ,就是活跃事务的最小值
  • Tmax, 是系统中最大事务ID(不管事务是否提交)

具体的判断流程如下:

  • RR隔离级别下,在每个事务开始的时候,会将当前系统中的所有的活跃事务拷贝到一个列表中(read view)
  • RC隔离级别下,在每个语句开始的时候,会将当前系统中的所有的活跃事务拷贝到一个列表中(read view) 
    并按照以下逻辑判断事务的可见性。 

四、MVCC解决了什么问题

  • MVCC使得数据库读不会对数据加锁,select不会加锁,提高了数据库的并发处理能力
  • 借助MVCC,数据库可以实现RC,RR等隔离级别,用户可以查看当前数据的前一个或者前几个历史版本。保证了ACID中的I-隔离性。

参考:

https://juejin.im/entry/58f86815ac502e00638e1c97

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
版本并发控制(MVCC)是MySQL中的一种技术,它通过维护数据的多个版本,以实现读写操作的并发控制。MVCC通过在每行记录后面保存两个隐藏的列(一个保存行的创建时间,一个保存行的删除时间)来实现。当一个事务读取数据时,它会根据事务开始的时间戳和行的版本信息来确定可见的数据版本。这种机制在InnoDB存储引擎中被广泛使用,可以提供一致性读操作的保证。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [MySQL之InnoDB存储引擎-MVCC](https://blog.csdn.net/qq_53267860/article/details/125073612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [MySQL数据库多版本并发控制MVCC](https://blog.csdn.net/iuu77/article/details/129132863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [mysql版本并发控制MVCC的实现](https://download.csdn.net/download/weixin_38607195/14907745)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haoxin963

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值