MVCC及其在leveldb中的实现

MVCC是一种并发控制机制,允许读写操作互不阻塞,主要用于解决并发环境下的脏读和不可重复读问题。MVCC通过维护不同版本的数据来实现,但在面对幻读问题时有限制,尤其在非只读查询时。文章提到了MVCC的版本管理和GC策略,以及在关系型数据库索引中的挑战,尤其是secondaryindex的处理。此外,还介绍了LevelDB中的MVCC实现,包括version引用计数和SSTable的管理。
摘要由CSDN通过智能技术生成

什么是MVCC

一种并发控制的方式---------多版本并发控制。其好处主要有两点1.写和读互相不阻塞,因为都是在各自的版本上进行。2.可以回溯之前的版本。MVCC只能解决部分幻读的问题(只读查询)快照读,如果对两个并发的非只读查询的来说,就有可能幻读,原因是执行INSERT、DELETE、UPDATE这些语句时)当前读)是加锁读最新的版本的。为在一个事务运行过程中,只有在对表中的记录做改动时(执行INSERT、DELETE、UPDATE这些语句时)才会为事务分配事务id,并且重新生成一个ReadView。然后我们根据MVCC ReadView判断数据行对当前事务是否可见的方式进行判断。具体可以看这个博客的部分。MVCC真的解决幻影读了吗?(事务隔离级别详解) - 掘金

当前读与快照读 - 简书

脏读、不可重复读的最终解决方案——MVCC - 知乎

这里主要记录一下不可重复读和幻读的理解。不可重复读可能是针对单个数据来说的,幻读是对数据总量来说的。解决方法------使用表级锁,锁定整张表,事务A多次读取数据总量之后才释放该锁,这个时候才允许其他事务新增数据。

快速理解脏读、不可重复读、幻读和MVCC - 腾讯云开发者社区-腾讯云

MVCC通用实现

读不加版本,写事务加了版本,还有一个txn status table来维护txn状态。

同时只依赖mvcc做不到serialsizable。如下图,t2要阻塞到RA读完提交才能创建新的version。

版本管理主要有下面三种方式

 同时版本不能一直增加,因为比较占空间。所以要gc

同时关系型数据库的index在多版本并发控制下也有一定的挑战

primary index要存储最新versiond的,也就是目前物理地址,同时如果修改pkey的话,是先delete,然后insert的。

但对于secondary index就复杂了。

第一种方法是通过主键来找,回表,但效率不高。第二种,就是 直接存物理地址,但是变化的话,所以的index都要变化

还有重复version的问题

解决方法有两个

就是要支持冗余的key,然后我们拿回来的data里面可能是多版本的,我们要有额外的逻辑来选择。

LevelDB中的MVCC

通过version引用计数,如果变为0的话,就从versionset链表中删除。实际上都是compaction时会记录SSTable变化。

 同时SSTable也是引用计数的,如果没有version引用的话,就可以删除了。

VersionEdit记录了每个次变化的文件。VersionEdit主要有两个作用一个就是应用到版本上作版本变迁,这个就是Builder做的事情,这主要发生在内存的数据结构中。另外一个作用就是持久化到MANIFEST记录版本变迁的内容(主要两个地方1.初始写入,需要写入当前数据状态的信息2.版本变迁写入,写入的是每一次版本变化的写入)。

当重新打开一个数据库时,需要读取MANIFEST重新构造版本信息,这个版本信息由初始的Version和多个VersionEdit生成,如果直接用VersionEdit应用会生成多个版本,降低了效率。所以使用了Builder,将多个VersionEdit的内容累积到Builder上,然后一次性应用到当前Version即可生成新的Version

同时每个操作都要sequnce number。应该是timestamp 和 mvcc组合起来的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值