理解了CU、CUDesc的基本结构,以及CUDesc的管理,或者说是其“代理”角色,列存的MVCC设计以及管理,实际上就非常好理解了。
由于列存的操作基本单位CU是由CUDesc表中的行进行管理的,因此列存表的CU可见性判断,也是由CUDesc的行头信息、按照传统的行存可见性进行判断的。
同样的,列存可见性的单位,也是CU级别(CUDesc),不同于行存的Tuple级别。
列存表的并发控制是CU文件级别的,实际上也等同于其CUDesc代理表的CUDesc行之间的并发控制。多个事务之间在一个CU上的并发管控,实际上取决于在其对应的CUDesc记录上是否冲突。例如:
- 两个事务并发去读一个CU是可进行的,两个事务都可以拿到此CU对应CUDesc行级别的share lock(共享锁)。
- 两个事务并发去更新一个CU,会因为在CUDesc上的锁冲突而触发一个事务回滚(当然,如果是read commited(读已提交)隔离级别并打开允许并发更新的开关,这里会做的事情是拿到此CUDesc最新版本的ctid,然后重跑一部分queryTree(查询树),来进行更新操作;此部分内容,详见第7章事务相关章节)。
- 两个事务并行执行,一个事务对一个CU执行了delete操作并先行提交,另一个事务在repeatable read(可重读)的隔离级别下,其获取的快照,只能看到这个CUDesc在delete发生前的版本,这个版本中的CUDesc中的delete_bitmap(删除位图),对应数据没有被标记删除。也由于CU的行删除是标记删除的机制,因此数据在原有CU的数据文件中依旧可用,此事务依旧可以在其对应的快照下读到对应行。

图9-30 删除CU中部分数据所进行的实际操作
删除CU中部分数据所进行的实际操作如图9-30所示。
从上面的几个例子可以看出,列存储对于更新的append only(仅允许追加)策略以及对于删除的标记删除方式,对于列存事务ACID的支持,是至关重要的。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




