openGauss内存引擎中的索引
一、索引
索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。
索引的作用就相当于目录的作用。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。
二、内存引擎
在 OpenGauss 中内存引擎全称为内存优化表(MOT)存储引擎。
内存引擎作为在 openGauss 中与传统基于磁盘的行存储、列存储并存的一种高性能存储引擎,基于全内存态数据存储,为 openGauss 提高了高吞吐的实时数据处理分析能力及极低的事务处理时延,在不同业务负载场景下可以达到其他引擎事务处理能力的 3~10 倍。内存引擎之所以有较强的事务处理能力,更多因为其全面利用内存中可以实现的无锁化的数据及其索引结构、高效的数据管控,基于 NUMA 架构的内存管控,优化的数据处理算法及事务管理机制。
MOT 与基于磁盘的普通表并排创建。MOT 的有效设计实现了几乎完全的 SQL 覆盖,并且支持完整的数据库功能集,如存储过程和自定义函数。通过完全存储在内存中的数据和索引、非统一内存访问感知(NUMA-aware)设计、消除锁和锁存争用的算法以及查询原生编译,MOT 可提供更快的数据访问和更高效的事务执行。MOT 有效的几乎无锁的设计和高度调优的实现,使其在多核服务器上实现了卓越的近线性吞吐量扩展。
图 1 OpenGauss 内存引擎架构图
三、Masstree
1.概要
Trie 树和 B+ 树结合而成的并发算法——MassTree。
1.1 因此首先介绍一下字典树(Trie 树)。
Trie 树,又叫字典树、前缀树(Prefix Tree)、单词查找树 或 键树,是一种多叉树结构。
图 2 一棵 Trie 树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”}。
Trie 树的基本性质:
1.根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
2.从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
3.每个节点的所有子节点包含的字符互不相同。
一般会在节点结构中设置一个标志,用来标记该结点处是否构成一个单词(关键字)。
1.2 然后再介绍一下 B+树。
图 3 B+树样例
B+树是 B 树的一种变种,有着比 B-树更高的查询性能
一个 m 阶的 B+树具有如下几个特征:
1.有 k 个子树的中间节点包含有 k 个元素(B 树中是 k-1 个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
2.所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3.所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。
从结构上来说,Mass Tree 是由一层或多层 B+ 树组成的 Trie 树。
图 4
图 4 中,圆形代表内部节点(interior node,也就是 B+ 树的 branch node),矩形代表边缘节点(border node,也就是 B+ 树的 leaf node),五角星代表 value。border node 的 value 域可能存放的是数据,也可能存放的是下一层子树的根节点。
Masstree 以键(key)的前缀作为索引,每 k 个字节形成一层 B+ 树结构,在每层中处理键中这 k 个 字 节 对 应 所 需 的 INSERT/LOOKUP/ UPDATE/DELETE 流程。图 4 为 k=8 的情况。
2.Masstree 静态数据结构
图 5
四、OpenGauss 中基于 Masstree 的索引
下面所有提到的大部分文件位于
openGauss-server-master\openGauss-server-master\src\gausskernel\storage\mot\core\src\storage\index 中
1.数据结构
对应文件位置:
openGauss-server-master\openGauss-server-master\src\gausskernel\storage\mot\core\src\storage\index\Masstree
OpenGauss 中对应 Masstree 的索引类名为 MasstreePrimaryIndex,
继承 Index 超类。
类 MasstreePrimaryIndex 拥有图 6 中的成员属性。
图 6
其超类 Index 拥有图 7 中的成员属性。
图 7
2.并发控制
为了防止读线程读到中间状态,叶节点被设计成最多存放 15 个 key,引入了一个 8 字节 64 位的 permutation(uint64_t),这个 permutation 被划分成 16 份,每份 4 位,其中 1 份代表当前节点的 key 数量,另外 15 份用于存放每个 key 在节点中实际位置的索引,key 的插入是顺序插入,之后只需要修改 permutation 来更新节点内 key 的索引信息,然后施加一个 release 语义,当读线程对这个节点的 permutation 施加 acquire 语义时,可以获取到完整的节点信息。
并发情况一般有两种竞争,OpenGauss 采用一个 32bit 的 version 参数应对并发控制。
图 8
write-write 竞争:同一时刻只有一个线程可以对当前节点进行写操作
read-write 竞争:开始前和读结束后都需要获取当前节点的最新 version,来判断在读过程中当前节点是否发生了写操作(插入或分裂),同时对节点的写操作都需要先修改 version,在插入 key 之前需要设置 inserting 标记,插入完成之后将 insert 的 vinsert + 1;在分裂之前需要设置 splitting 标记,分裂完成之后将 split 的 vsplit + 1。
3.查找操作
图 9
首先,在开始读取节点之前,必须获得节点的 stable version,即 version 中的 inserting 和 splitting 位都为 0。
其次,在下降之前,需要获取最新的 root,因为在开始下降前,根节点可能分裂了,导致其发生了改变。
最后,如果当前节点已经是叶节点,那么可以返回,否则需要进行下降,读取内部结点根据 key[x, x+8)(8 字节) 获得下降节点之后,分为 3 种情况处理:
1.节点在我们读取期间没有发生任何变化,我们可以安全地进行下降;
2.节点发生了变化,而且是分裂,那么我们需要从根节点重新进行下降;
3.节点发生了变化,但只是插入,只需要重新对当前节点进行下降。
- 插入操作
图 10
查找 key,如果找到 key 则 tree 不做改变;如果没找到,
1.先锁住应该持有待插入 key 的节点
2.将相应节点 version 修改为 inserting
3.将相应节点 state 修改为 insert
4.更新树结构,以满足约束
5.更新在叶节点中的 key slice ,keylen, key suffix ,key vaule
6.Add the key's location in permutation's back.在解锁节点并将密钥输入到排列中之后将在 finish_insert(从 lp.finish 调用)中完成。
图 11 OpenGauss 内存引擎索引上插入操作代码部分
图 12
在 lp.finish 传入第一个参数为 1 时,调用 finish_insert,finish_insert 函数中实现通过在 permutation 插入新增节点的 index 使得节点对外可见。
5.删除操作
这里只讨论逻辑删除。
逻辑删除和 B+树的类似,但是并不对 key 少的节点进行合并,当节点 key 减少到 0 时,需要标记这个节点为 deleted,然后将其从父节点删除,同时如果是叶节点的话,还需要维护叶节点的双向连接。如果某棵子树为空的话也可以删除整棵子树。当其他线程发现节点处于 deleted 状态时,需要进行重试,因为这个节点逻辑上是不存在的。
图 13
删除操作可能会遇到图 13 的情况,左边的线程根据 k1 定位到了位置 i,在读取 v1 之前这个节点发生了删除位于位置 i 的 k1,同时在位置 j 处插入 k2,如果 i 等于 j,可能导致左边的线程读取到 v2,为了解决这个问题,需要在索引 i 被删除后重新利用时增加节点的 vinsert 域。
图 14 OpenGauss 内存引擎索引上删除操作代码部分
图 15 lp.finish 传入参数为-1 时,调用 finish_remove 函数,通过在 permutation 中删除节点索引已达到逻辑删除作用
openGauss内存引擎中的索引的更多相关文章
- 聊一聊 InnoDB 引擎中的索引类型
索引对数据库有多重要,我想大家都已经知道了吧,关于索引可能大家会对它多少有一些误解,首先索引是一种数据结构,并且索引不是越多越好.合理的索引可以提高存储引擎对数据的查询效率. 形象一点来说呢,索引跟书 ...
- InnoDB 引擎中的索引类型
首先索引是一种数据结构,并且索引不是越多越好.合理的索引可以提高存储引擎对数据的查询效率. 形象一点来说呢,索引跟书本的目录一样,能否快速的查找到你需要的信息,取决于你设计的目录是否合理. MySQL ...
- InnoDB引擎中的索引与算法9
5.1 InnoDB支持以下几种常见的索引: B+树索引 全文索引 哈希索引(自适应哈希索引) 关于哈希索引的说明: -- 1.InnoDB的哈希索引是自适应的,其根据表的使用情况自动生成哈希索引,不 ...
- 聊一聊 InnoDB 引擎中的这些索引策略
在上一篇中,我们简单的介绍了一下 InnoDB 引擎的索引类型,这一篇我们继续学习 InnoDB 的索引,聊一聊索引策略,更好的利用好索引,提升数据库的性能,主要聊一聊覆盖索引.最左前缀原则.索引下推 ...
- 数据库基础知识详解五:MySQL中的索引和其两种引擎、主从复制以及关系型/非关系型数据库
1.MySQL中的索引 在MySQL,索引是由B+树实现的,B+是一种与B树十分类似的数据结构. 形如下面这种: 其结构特点: (1)有n课子树的结点中含有n个关键码. (2)非根节点子节点数: ce ...
- 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)
使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...
- 在MySQL的InnoDB存储引擎中count(*)函数的优化
写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引.使用事务.要什么select什么等等.然而,只是停留在阅读的层面上,很少有实践,因为没有遇到真实的项目,一切都是纸上谈兵.实践是检验 ...
- 转载: SQL Server中的索引
http://www.blogjava.net/wangdetian168/archive/2011/03/07/347192.html 1 SQL Server中的索引 索引是与表或视图关联的磁盘上 ...
- (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁
表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...
- MySQL技术内幕InnoDB存储引擎(表&索引算法和锁)
表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示 ...
随机推荐
- 【Azure 事件中心】Flink消费Event Hub中事件, 使用Azure默认示例代码,始终获取新产生的事件,如何消费旧事件呢?
问题描述 根据Azure Event Hub示例文档,[将 Apache Flink 与适用于 Apache Kafka 的 Azure 事件中心配合使用],配置好 consumer.config 文 ...
- Springboot 撞上 NebulaGraph——NGbatis 初体验
本文首发于 NebulaGraph 公众号 https://mp.weixin.qq.com/s/z56o6AEz1Z4RmS8Zdx6dTA 大家好,我是开源项目 NGbatis 的发起人大叶(Co ...
- [linux 爬坑] 几个linux发行版尝试和令人崩溃的ssr安装体验
最近电脑上的manjaro好像出了问题,长时间不用就会死机.也懒得追究原因了,正好决定尝试几个发行版.首先尝试安装银河麒麟 这个发行版实际上就是ubuntu,甚至源什么的都是ubuntu的,也不 ...
- Java static 关键字的使用 小练习
1 package com.bytezreo.statictest2; 2 3 /** 4 * 5 * @Description static 关键字的使用 小练习 6 * @author Bytez ...
- electron暴露配置文件(用户可随时修改)
配置文件 一般web前端项目配置文件,写死的放在src/config下,需要打包配置的放在.env文件中.但在electron项目中,如果配置数据更改,需要每次给用户打包升级肯定是行不通的.于是外部配 ...
- PostgreSql一个月学习计划
1.背景 国内使用数据库最多的莫过于mysql,大部分程序员第一次接触数据库就是mysql.(毕竟免费的 = =!)但近年来,有一些黑马出现(如下图),其中表现最突出的莫过于PostgreSQL.特规 ...
- inner join on 1=1 在查询中的高级用法
最近在项目中看到一个查询语句,让我有兴趣去研究.研究.查询语句如下: 重点分析第二个INNER JOIN ON 1 = 1 这个语句:内连接表示查询两个表的交集,而且ON的条件为 1=1 就表示连接 ...
- 在linux上安装redis并设置权限
redis是使用 c 开发,启动文件是二进制的看不到什么有用的信息,安装最新版本可以在https://redis.io/download 官网上查看,安装非常简单: mkdir /usr/redis, ...
- linux-关于conio.h文件的文件缺失问题
链接: https://pan.baidu.com/s/1Qzo4CkJB1_5E-3rDLtfG4Q 提取码: fh65 编辑以下这个依赖库就可以了 $ cd libconio-1.0.0 $ ./ ...
- 记录--UNI-APP安卓本地打包详细教程(保姆级)
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.开发环境 uni-app 官方文档地址 原生开发者支持 1.Android Studio 下载地址:Android Studio官网 ...