您的位置:首页 > 数据库

数据库的MVCC的机制的理解

2018-01-13 14:28 120 查看
参考:

1、https://www.zhihu.com/question/62125049/answer/195568837

2、《深入浅出INNODB MVCC机制与原理》

https://wenku.baidu.com/view/69d5c129192e45361066f5fb.html

 几种典型MVCC的机制说明(很清晰)

1、  一种多版本并发控制的机制:可以用B+树来支撑实现MVCC。叶子节点可以对应表的一行,Value行为可以用链表串起来的操作。这样,不会阻塞读(因为写操作都挂在链表上,没有直接修改原始数据)。

2、  当然,索引还可以是其他类型的,根据自己实现喜好。比如:也可以是Hashtable ,RocksDB和MemSQL用到的是skiplist(跳跃表),微软Hekaton用的是bw-tree,Hyper用的是apative radis tree等。

3、  B+树挺好,对范围、点查询都不错,可以性能很高。文中说选择Skiplist是认为简单。

4、  以下说明几种具体形式

1)  数据存在row里,新版本在前。



读的时候,会带一个snapshot version。比如是7,则读取到v=6的那个地方就可以了。

优点:如果更新不频繁,链表会比较短。大部分查询很快就能找到。

缺点:更新时,需要申请新的空间。还需要调整索引(因为是B+树中的节点,代价还是有的)。

 

2)  数据存在row里,老版本在前



与上面的类似,不过存数据顺序反了一下。

优点:新版本直接挂最后,不需要调索引。

缺点:查询时候,需要多次查找,多次访问内存,性能慢。

写快读慢

 

3)  追加的是增量数据,定期做压缩



V0->V1,只发生了4的变化,则V1只记录4。

优点:因为有Row做接力,不需要调整索引,对第一种是改进。

      只保存增量数据,内存空间占用小。

缺点:查询时候就比较麻烦,得累计起来才行。不过通过定期的压缩归并,减少链表长度,减轻这个问题。

4)  数据存到一块连续内存中



前面几种方法,都是用链表形式。新插入数据,新申请内存。在做Scan的时候(主要就是大量连续读,OLAP中考虑会多一些。),会比较慢。先对索引Scan,再找数据。文章中计算100ns一次内存访问,读索引会消耗,推出每秒扫描数据量上线1s/100ns=1000万。不过现在处理器多通道,可能不一定这样算,但这里的理论向表明这样去查找总是有看得见的性能瓶颈。

 

解决思路就是:申请一块大内存,然后把每一行存到这个数组里,定长数据直接存,变长数据用指针,对于小字符串,可以做一个优化,将字符串分成2部分,前面小的一部分可以直接存数据里,然后通过指针指向另一部分。

做点查询的时候,通过索引查,做scan的时候,看查询的数据情况,当数据量大时,直接scan数组是更快的,数据量小时,仍然通过索引做范围查找。

优点:一些情况下,Scan性能好。

缺点:原地更改row里的数据,读写的时候都需要加锁(latch),更新多的时候,对读不友好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: