gydtep
发表于 2021-12-22 19:46:25
事务型应用和分析型应用对存储引擎有着截然不同的要求,前者要求索引可以精确定位到每一行并支持高效的增删改,而后者则需要支持高效批量扫描处理,这两个场景对存储引擎的设计要求完全不同,有时甚至是矛盾的。
gydtep
发表于 2021-12-22 20:13:37
管理运维方便,用户无需关注数据在两套系统之间同步及数据一致性问题。
PolarDB 采用了和Oracle/Sql Server等商用数据库类似的行列混合存储技术,我们称之为In-Memory Column Index:
gydtep
发表于 2021-12-22 21:07:46
PolarDB 采用了和Oracle/Sql Server等商用数据库类似的行列混合存储技术,我们称之为In-Memory Column Index:
建表时可以指定部分表或者列为列存格式,或者对已有的表可以使用Alter table语句为其增加列存属性,分析型查询会自动使用列存格式来进行查询加速。
gydtep
发表于 2021-12-23 08:18:09
由于有一个久经考验的行存系统的存在,列存系统出现任何问题,都可以切换回行存系统响应查询请求。
上述条件可谓有利有弊,这也影响了对PolarDB整个行列混合存储的方案设计。
gydtep
发表于 2021-12-23 08:41:33
在MySQL插件式的存储引擎框架的架构下,增加列存支持最简单方案是实现一个单独的存储引擎,如Inforbright以及MarinaDB的ColumnStore都采用了这种方案。而PolarDB采用了将列存实现为InnoDB的二级索引的方案,主要基于如下几点考量:
gydtep
发表于 2021-12-23 09:56:32
对于上面的表其主表(Primary Index)包含(C1,C2,C3,C4,C5) 5列数据, Seconary Index索引包含(C2,C1) 两列数据, 在普通二级索引中,C2与C1编码成一行保存在B+tree中。而其中的列存索引包含(C2,C3,C4)三列数据. 在实际物理存储时,会对三列进行拆分独立存储,每一列都会按写入顺序转成列存格式。
gydtep
发表于 2021-12-23 10:15:36
列存数据组织
对ColumnIndex中每一列,其存储都使用了无序且追加写的格式,结合标记删除及后台异步compaction实现空间回收。其具体实现上有如下几个关键点:
gydtep
发表于 2021-12-23 13:36:19
采用这种数据组织方式一方面满足了分析型查询按列进行批量扫描过滤的要求。另一方面对于TP型事务操作影响非常小,写入操作只需要按列追加写到内存即可,删除操作只需要设置一个删除标记位。而更新操作则是一个标记删除附加一个追加写。列存可以做到支持事务级别的更新同时,做到几乎不影响OLTP的性能。
gydtep
发表于 2021-12-23 14:59:04
在每个Active Datapack终结写入的时候,会预先进行计算,并生成Datapack所包含数据的最小值/最大值/数值的总和/空值的个数/记录总条数等信息。所有这些信息会维护在DataPacks Meta元信息区域并常驻内存。由于冻结的Datapack中还会存在数据的删除操作,因此统计信息的更新维护会放到后台完成。
gydtep
发表于 2021-12-23 15:40:10
第三种方式,RW/RO支持OLTP型负载,在单独的Standby节点开启行列混合存储以支持AP型查询,由于standby是使用独立的共享存储集群,这种方案在第二种方案支持CPU和内存资源隔离的基础上,还可以实现IO资源的隔离。
页:
1
2
3
4
5
[6]
7
8
9
10
11
12
13
14
15