前文回顾:

1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1)

2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2)

3.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(3)

4.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(4)

5.如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(1)

6.如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(2)

7.如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(1)

8.如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(2)

9.如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(3)

目录

  • openGauss数据库SQL引擎

  • openGauss数据库执行器技术

  • openGauss存储技术

一、openGauss存储概览

二、openGauss行存储引擎

三、openGauss列存储引擎

Ⅰ、列存储引擎的总体架构

Ⅱ、列存储的页面组织结构

Ⅲ、列存储的MVCC设计

IV、列存储的索引设计

V、列存储自适应压缩

VI、列存储的持久化设计

四、openGauss内存引擎

  • openGauss事务机制

  • openGauss数据库安全

openGauss存储技术

三.openGauss列存储引擎

传统行存储数据压缩率低,必须按行读取,即使读取一列也必须读取整行。在分析性的作业以及业务负载的情况下,数据库往往会遇到针对大量表的复杂查询,而这种复杂查询中往往仅涉及一个较宽(表列数较多)的表中个别列。此类场景下,行存储以行作为操作单位,会引入与业务目标数据无关的数据列的读取与缓存,造成了大量IO的浪费,性能较差。因此openGauss提供了列存储引擎的相关功能。创建表的时候,可以指定行存储还是列存储。

总体来说,列存储有以下优势:

(1) 列的数据特征比较相似,适合压缩,压缩比很高,在数据量较大(如数仓)场景下会节省大量磁盘空间;压缩比高同时也会提高单位作业下的IO效率。

(2) 当表中列数比较多,但是访问的列数比较少时,列存储可以按需读取列数据,大大减少不必要的读IO,提高查询性能。

(3) 基于列批量数据向量运算,结合向量化执行引擎,CPU的缓存命中率比较高,性能比较好,更适合OLAP大数据统计分析的场景。

(4) 列存储表同样支持DML操作和MVCC,功能完备,且在使用角度做了良好的兼容,基本是对用户透明的,方便使用。

列存储引擎的总体架构

01

列存引擎的存储基本单位是CU(Compression Unit,压缩单元),即表中一列的一部分数据组成的压缩数据块。行存引擎中是以行作为单位来管理,而当使用列存储时,整个表整体被按照不同列划分为若干个CU,实例如图25所示。

图25 CU划分方式

如图25所示,假设以6万行作为一个单位,则一个12万行、3列宽的表,则被划分为8个CU,每个CU对应一个列上的6万个列数据。图中有Col0、Col1、Col2、Col3四列,数据按照行切分了两个Row group(行组),每个Row group有固定的行数。针对每个Row group按照列做数据压缩,形成压缩单元CU(Compression unit)。每个Row group内部各个列的CU的行边界是完全对齐的。当然,大部分时候,CU在经过压缩后,因为数据特征与压缩率的不同,文件大小会完全不同,例如图26所示。

图26  压缩单元示意图

为了管理表对应的CU,与执行器层进行对接来提供各种功能,列存储引擎使用了CUDesc(压缩单元描述符)表来记录一个列存表中CU对应的元信息,如图27所示。

图27  列存引擎整体架构图

注:Cmn 表示第m列的cuid是n的压缩单元。

每个CU对应一个CU Desc的记录,在CU desc里记录了整个CU的事务时间戳信息、CU的大小、存储位置、magic校验码、min/max等信息。

与此同时,每张列存表还配有一张Delta表,Delta表自身为行存储表。当有少量的数据插入到一张列存表时,数据会被暂时放入Delta表,等到到达阈值或满足一定条件或操作时再行整合为CU文件。Delta表可以帮助我们避免单点数据操作带来的很重的CU操作与开销。

设计采用级别的多版本并发控制,删除通过引入Virtual Column Bitmap来标记删除。Bitmap是多版本的。

 列存储的页面组织结构

02

上面讲到了CUDesc表以及其用来记录元信息的目的。CUDesc的典型结构如图28。

图28  CUDesc的典型结构

其中:

(1)_rowTupleHeader为传统行存记录的行头,其中包含了前面提到过的事务以及位置信息等,用来进行可见性判断等。

(2)cu_mode实际为此CUDesc对应CU的infomask,记录了一些CU的特征信息(比如是否Full,是否有NULL等等)

(3)magic是CUDesc与CU文件之间校验的关键信息。

(4)min/max(最小值/最大值)为稀疏索引,后续会进一步展开。

而CU文件本身结构,则如图29所示。

图29  CU文件本身结构

列存储在CUDesc表的存储信息基础上设计了一套与上层交互的操作API。除了上面列存储的页面组织结构以及文件管理中天然可以展示出的结构机制之外,列存储还有一些关键的技术特征:

(1)列存储的CU中数据的删除,实际上是标记删除。删除操作,相当于是更新了CUDesc表中CU对应CUDesc记录的delete bitmap(删除位图)结构,标记列中某行对应数据已被删除,而CU文件数据不会被更改。这样可以避免删除操作带来的IO放大以及解压、压缩的高额CPU开销。这样的设计,也可以使得对于同一个CU的select(查询)和delete(删除)互不阻塞,提升并发能力。

(2)列存储CU中数据更新,则是遵循append-only(仅允许追加)原则的,即CU文件仅会向后进行延展扩充,亦或是启用新的CU文件,而不是在对应行在CU中的位置就地更新。

(3)由于CU以及CUDesc的元数据管理模式,原有系统中的Vacuum机制实际上并不会非常有效的清除CU中已经失效的存储空间,因为Lazy Vacuum(清理数据时,只是标识无用行的状态可以录入新数据,不会影响对表数据的操作)仅能在CUDesc级别进行操作,在多数场景下无法对CU文件本身进行清理。列存储内部如果要对列存数据表进行清理,需要执行Vacuum Full(除了清理无用行,还会合并数据块,整个过程会锁定表)操作。

列存储的MVCC设计

03

理解了CU、CUDesc的基本结构,以及CUDesc的管理,或者说是其“代理”角色,列存的MVCC设计以及管理,实际上就非常好理解了。

由于列存的操作基本单位CU是由CUDesc表中的行进行管理的,因此列存表的CU可见性判断,也是由CUDesc的行头信息、按照传统的行存可见性进行判断的。

同样的,列存可见性的单位,也是CU级别(CUDesc),不同于行存的Tuple级别。

列存表的并发控制是CU文件级别的,实际上也等同于其CUDesc代理表的CUDesc行之间的并发控制。多个事务之间在一个CU上的并发管控,实际上取决于在其对应的CUDesc记录上是否冲突。例如:

(1)两个事务并发去读一个CU是可进行的,两个事务都可以拿到此CU对应CUDesc行级别的share lock(共享锁)。

(2)两个事务并发去更新一个CU,会因为在CUDesc上的锁冲突而触发一个事务回滚(当然,如果是read commited(读已提交)隔离级别并打开允许并发更新的开关,这里会做的事情是拿到此CUDesc最新版本的ctid,然后重跑一部分queryTree(查询树),来进行更新操作;此部分内容,详见第7章事务相关章节)。

(3)两个事务并行执行,一个事务对一个CU执行了delete操作并先行提交,另一个事务在repeatable read(可重读)的隔离级别下,其获取的快照,只能看到这个CUDesc在delete发生前的版本,这个版本中的CUDesc中的delete_bitmap(删除位图),对应数据没有被标记删除。也由于CU的行删除是标记删除的机制,因此数据在原有CU的数据文件中依旧可用,此事务依旧可以在其对应的快照下读到对应行。

图30  删除CU中部分数据所进行的实际操作

删除CU中部分数据所进行的实际操作如图30所示。

从上面的几个例子可以看出,列存储对于更新的append only(仅允许追加)策略以及对于删除的标记删除方式,对于列存事务ACID的支持,是至关重要的。

未完待续.......


若您对本系列文章感兴趣,敬请关注我们的公众号,我们将在每周二、周四进行更新。

更多数据库行业相关内容,欢迎光临 2021 数据技术嘉年华 :https://www.modb.pro/dtc2021(扫描下方二维码免费预约大会直播)。

END

推荐阅读:267页!2020年度数据库技术年刊

推荐下载:2020数据技术嘉年华PPT下载

2020数据技术嘉年华近50个PPT下载、视频回放已上传墨天轮平台,可在“数据和云”公众号回复关键词“2020DTC”获得!

你知道吗?我们的视频号里已经发布了很多精彩的内容,快去看看吧!↓↓↓

点击下图查看更多 ↓

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看”

你的喜欢会被看到❤

【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(4)相关推荐

  1. 【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(7)

    前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握openGauss数据库 ...

  2. 【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(6)

    前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握openGauss数据库 ...

  3. 【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(5)

    前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握openGauss数据库 ...

  4. 【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(3)

    前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握openGauss数据库 ...

  5. 【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(2)

    前文回顾: 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 如何掌握openGauss数据库核心技术?秘 ...

  6. 【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(1)

    前文回顾: 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 如何掌握openGauss数据库核心技术?秘 ...

  7. 【连载】如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(4)

    前文回顾: 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 如何掌握openGauss数据库核心技术?秘 ...

  8. 【连载】如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2)

    基于周二的文章<如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1)>(详戳),我们今日继续连载. 目录 openGauss数据库SQL引擎 openGauss数据库执行 ...

  9. 【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(4)

    点击蓝字 · 关注我们 前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握 ...

最新文章

  1. MSDN中关于变体数据类型
  2. 《用Python进行自然语言处理》第2章 获得文本语料和词汇资源
  3. 微型计算机2013年10月下,微型计算机及接口技术2013年10月真题试题(04732)
  4. SQL点滴12—SQL Server备份还原数据库中的小把戏
  5. 首个自贸港“跨境数据交互试点”!中国电信海南国际数据中心将助推5G、大数据等产业发展...
  6. [SpringSecurity]web权限方案_CSRF功能
  7. JAVA之outofmemory
  8. 合成器插件Sylenth1 2.2.1绿化版亲测有效
  9. 矩阵论(四)——矩阵的广义逆
  10. AIX虚拟内存管理机制(转)
  11. Springboot+mybatis
  12. 2021年危险化学品经营单位主要负责人考试及危险化学品经营单位主要负责人找解析
  13. 【机器学习系列】聊聊决策树
  14. linux下的“超超超音速”安装谷歌中文输入法
  15. [网盘工具/百度网盘]秒传链接的使用 -2022版油猴网页脚本
  16. ARM知识扫盲-RISC架构-ARM寄存器-ARM指令集
  17. 【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍
  18. mysql备份脚本 shell_linux中mysql备份shell脚本代码 相关自动化脚本
  19. python编程题:三次方格式化
  20. Keil颜色配置(黑底,不同种类字不同颜色)

热门文章

  1. 开源合规处理方法_经济高效的开源软件许可合规模型
  2. 开放app开放login_开放值得付出努力吗?
  3. HTML5 Canvas中处理图像和视频
  4. 源码编译OpenCV卡在ippicv
  5. log4j mysql_log4j写入mysql数据库 | 学步园
  6. python的except之后还运行吗_python except异常处理之后不退出,如何解决异常继续执行...
  7. ansys用什么cpu_ansys参数化建模教程专栏——以例子吹爆APDL的省时省力(一)。...
  8. linux内存迁移,性能优化:使用Ramlog将日志文件转移到内存中
  9. bootstraptable设置行高度_【短柱专题】窗台板为什么要通长设置
  10. 第二章 信息的表示和处理