GaussDB关键技术原理:高弹性(三)

news2024/12/25 14:48:31

书接上文GaussDB关键技术原理:高弹性(二)从优化器剪枝、执行器两方面对hashbucket进行了解读,本篇将从段页式技术方面继续介绍GaussDB高弹性技术。

3 段页式  

3.1 段页式存储  

根据前文的介绍,hashbucket需要对文件进行分片,如果直接对单文件管理的数据文件进行切片,将会产生表数量*1024个文件,在表数量较多的场景下,产生的小文件数量多,导致文件管理系统的压力较大,因此,引入段页式管理,属于一个库表空间下的所有表共同使用一组段页式文件,防止bucket化拆分后小文件多的问题。

图1是存储引擎架构示意图,从整个数据库的组成架构看,段页式在其中是存储引擎中最底层的一种文件管理方式,和单文件管理相并列,通过一组段页式文件管理所有用户表,减少单文件数量,从而降低文件系统的压力。段页式管理和单文件管理通过smgr层(介质管理器)对上层提供相同的接口,实现和缓冲区的读写交互,上层业务不感知底层存储方式发生的变化。

图1  存储引擎整体架构示意图

为了向SQL层提供一套接口,段页式表引入了逻辑block的概念,逻辑block是连续页号的page,上层逻辑访问段页式表使用的是逻辑block。每个段页式表都有一个对应的SegmentHeader,SegmentHeader维护了段页式表使用的逻辑block到实际的段页式物理block的映射关系。SegmentHeader管理了一个用户表的所有元数据信息,尤为重要,设计如下:

typedef struct SegmentHead {    
    uint64 magic;
    XLogRecPtr lsn;
    uint32 nblocks;       // block number reported to upper layer
    uint32 total_blocks; // total blocks can be allocated to table (exclude metadata pages)
    uint64 reserved;
    BlockNumber level0_slots[bmt_header_level0_slots];
    BlockNumber level1_slots[bmt_header_level1_slots];
    BlockNumber fork_head[segment_max_forknum + 1];
} SegmentHead;

其中,比较重要的有:

  • nblocks指的是上层看到的最大逻辑页号,和页式存储中的文件大小的概念是一样的,smgrnblocks的返回值。

  • total_blocks指的是分配的所有extent,数据块的个数总和,当申请的extent的pages全部用完时,会再申请一个extent。

  • level0_slots和level1_slots存放的是逻辑block到物理block的映射关系,对于序号靠前的extent,起始位置直接存储在 level0_slots中。level0_slots存满之后,会使用level1_slots中存放的level0_slots页面记录。

  • fork_head指的是所有fork的segment head,也以数组的形式存储在main fork的segment head中。每个segment head中的 fork_head[0] 一定等于自己。

hashbucket表采用了段页式存储的方式。在段页式存储管理下,表空间和数据文件采用段(Segment)、区(Extent)以及页(Page/Block)作为逻辑组织,进行存储的分配和管理。具体来说,一个database在其所存在的每个表空间中,都拥有一组独立的段页式文件,如下图2所示:某个库下的一个表空间的段页式文件由1-5号文件组成。    

图2  段页式物理结构示意图

由于属于一个表空间下的所有段页式表的数据都会写到这几个段页式文件中,所以这几个文件会膨胀到TB量级,段页式文件仍然沿用GaussDB页式文件的切分方式,按照1GB进行切分,将一个物理文件称为一个slice,使用2.1, 3.1来表示。拥有相同前缀的一组slice组成一个段页式文件管理系统(SegLogicFile)。SQL层将每个SegLogicFile看作一个无限大的物理文件。

每个SegLogicFile称为一个ExtentGroup,文件组织格式如下图3。

图3  段页式逻辑文件组织格式

  • MapHeader:用来存放管理BitMap page的元信息;

  • BitMapPagesBitmap页面,用来管理DataPages的extent使用情况,页面中的一个bit位表示代表1个extent,0表示空闲,1表示已使用。每个ExtentGroup中extent大小不一样,所以1个bit位表示的extent大小也不一样;

  • ReversePointerPages:reversepointer页面,用来管理DataPages的extent的属主信息,即属于哪个SegmentHeader管理。

  • DataPages:数据表记录存放区域,不同文件按照不同数量的block组成extent。

GaussDB中有fork的概念,用于管理每个表的数据和元数据信息,如表数据存的文件称作MAIN FORK,空闲页面信息称为FSM FORK,visibility map称为VM FORK。这些fork存储在各自的物理文件中,文件用后缀来区分,1_fsm, 1_vm,MAIN FORK不带后缀。所以,对于GaussDB单文件存储来说,只需要知道relfilenode和fork number,就能拼出物理文件名。    

为了前向兼容,段页式保留了fork的概念,一个fork使用一组segment,依然用“relfilenode + fork number +逻辑页号”来访问数据。把MAIN FORK的SegmentHeader,作为该表的relfilenode,存储在系统表pg_class中;其它fork的SegmentHeader存储在MAIN FORK的SegmentHeader中。数据访问的流程如下图4所示:

图4  段页式数据访问流程示意图

其中,表t1在pg_class中的relfilenode是4157,通过访问段页式1号文件的4157页面可以访问到其SegmentHeader,根据上层传入的逻辑页面号0可以通过Block Map Tree找到物理页面的位置(2号文件的4157页面)。通过fork header中的fsm页面4160可以访问到fsm的segmentheader所在的物理信息(1_fsm文件的4160页面)。

由上可知,段页式表通过唯一的Segment Header进行表示,而段页式表中的数据则是存放在若干个Extent中,每个Extent都是由固定数量的Page组成的。所有Extent由1-5号文件组成段空间,所有表都从该段空间中分配数据。因此表的个数和实际物理文件个数无关。每个表有一个逻辑segment,该表所有的数据都存在该segment上。每个segment会挂载多个extent,每个extent是一块连续的物理页面。    

在表或者分区数量较多的场景下, 段页式存储相比于页式存储生成的文件数量会大大减少,从而降低对文件系统的规格要求,减轻对操作系统IO栈产生的压力,提升数据库的吞吐能力。hashbucket表对数据文件进行切片,如果不采用段页式存储可能会产生大量的小文件,在进行CHECKPOINT这种IO重度操作的时候,需要对大量文件进行sync操作,此时很有可能造成长时间的IO等待,影响数据库的整体性能。

段页式目前支持五种大小的Extent,分别是8K/64K/1M/8M/32M,对应五种不同Extent大小的段页式文件(文件名1/2/3/4/5),称之为段页式文件组,这一组文件中1号文件用来管理段页式表元数据,2到5号文件用来存储用户表数据。对于一个segment来说,每一次扩展的Extent的大小是固定的。前16个extent大小为64K,第17到第143个extent大小为1MB,依次类推。具体参数如下表1所示。初始时表比较小,分配的Extent粒度较小,当表变得比较大的时候,分配的粒度较大。这样做的好处是可以在空间利用率和分配频率之间做一个很好的平衡。

表1  段页式支持的不同extend的参数表

Group

Extent size

Extent page count

Extent count range

Total page count

Total size

1

64K

8

[1, 16]

128

1M

2

1M

128

[17, 143]

16K

128M

3

8M

1024

[144, 255]

128K

1G

4

32M

8192

[256, …]

因为Extent的扩展方式是固定的,因此任何一个Segment中的Extent的分布都相同,如下图5所示:Extent在逻辑上是连续的,物理上Segment分布在1号文件,Extent分布在段页式2-5号文件的任意位置。    

图5  segment中extend的分布示意图

3.2 hashbucket段页式  

hashbucket位于段页式的下层,将段页式的文件组bucket化分片,如下图6所示:

图6  hashbucket在存储引擎架构中的位置

hashbucket表的bucket桶个数固定为1024个。每个DN分片拥有的bucket数量为1024/DN分片数量个。将上一章节介绍的段页式文件(1-5号)进行切片,拥有相同hash值的数据存在一组bucket段页式文件中,命名方式为文件编号_bucketid_[vm/fsm],其中1号小bucket段页式文件仍然存储元数据信息,主要是SegmentHeader,管理属于bucket 0的数据Extent;2号小bucket段页式文件存储真正的用户数据。因此以tablespace为粒度,每个库的每个tablespace拥有1024组1-5号bucket段页式文件。    

hashbucket表与段页式的寻址方式类似,在系统表pg_class的relfilenode表示1号段页式文件中的一个页面号,表示最上层的元数据管理页面,通过如下结构体实现:

typedef struct BktMainHead {
    uint64 magic;
    XLogRecPtr lsn;
    BlockNumber bkt_main_head_map[BUCKETMAPLEN];
} SegmentHead;

其中,bkt_main_head_map是4字节*1024的数组,下标表示hashbucket桶的编号,内容表示小段页式文件中SegmentHeader所在的页面号。

以创建一张hashbucket表t1为例,寻址过程如下图7所示:

图7  hashbucket建表寻址过程示意图

  • P1:通过pg_class的relfilenode能够访问到段页式1号文件中的BktMainHead页面4157。    

  • P2:从BktMainHead的内容找到对应bucket 0 SegmentHeader所在的页面号,访问对应bucket 0的1号文件1_b0的页面65。

  • P3:通过页面1_b0的页面65的SegmentHeader记录的Extent位置信息存入对应的数据,或者根据传入的逻辑页面号翻译出要访问的物理页面位置。

  • P4:根据要访问的物理页面信息访问对应的bucket段页式文件2_b0。

  • hashbucket的元数据管理采用上述方式主要为了后续扩容考虑,为了实现物理文件搬迁,我们需要直接把某个DN分片的bucket文件搬迁到新节点,为了保证文件搬迁后仍然可以寻址成功,需要在新DN build完元数据之后进行BktMainHead的更新,将即将搬迁至新节点的所有bucket 1号文件中的SegmentHeader所在的页面号更新到段页式1号文件的BktMainHead中。

hashbucket表的反向指针在bucket 1号文件中,SegmentHeader页面对应的反向指针存储的是1号段页式文件BktMainHead页面所在的页面号,因此需要在扩容期间基线数据搬迁完成时更新搬迁至新节点所有bucket 1号文件的SegmentHeader的反向指针。

3.3 TOAST  

TOAST是GaussDB中一种存储大数据的机制。TOAST表是否创建是根据原表列类型决定的,数据是否存到TOAST表中是根据数据大小决定的。创建原表时如果包含变长类型(text类型等)的列就会自动创建并关联TOAST表一张TOAST表负责行外存储,如下图8所示。GaussDB不允许一行数据跨页存储,当单个元组大小超过2K时,会自动触发TOAST机制,对数据进行压缩和切片,将实际数据存储到TOAST表。TOAST表不支持用户手动创建,随原表一起创建和删除。TOAST表和索引的存储类型和原表保持一致,原表和TOAST表通过OID关联,pg_class中原表会记录reltoastrelid(与原表关联的TOAST表的OID,如果没有则为0),在pg_class中通过OID可以找到TOAST表。    

图8  hashbucket TOAST表元数据

3.3.1 hashbucket TOAST数据管理方式  

由于hashbucket扩容会将属于老节点的文件直接搬迁至新节点,此时如果TOAST指针中记录了老节点的OID信息,由于OID是本地维护的,搬迁到新节点可能出现访问不到数据的问题。因此,hashbucket表TOAST数据管理方式是由产生TOAST的列存储TOAST指针,存储小段页式1号文件的relfilenode。对TOAST表操作时通过小段页式1号文件SegmentHead页面的反向指针查询到当前hashbucket表大段页式1号文件的页面号,再通过反向指针获取到所属TOAST表的OID,如下图9所示:    

图9  hashbucket TOAST表寻址示意图

数据插入时会先对可压缩的列执行压缩,然后判断元组长度是否能触发TOAST以及类型是否可以执行外部存储,多数情况下压缩后的元组长度不满足2K的阈值所以不会触发TOAST机制。访问数据时需要访问TOAST表中的压缩数据,对该数据解压。

关键数据结构TOAST指针varatt_external,存储获取行外存储数据所需的信息,数据结构设计如下:

typedef struct varatt_external {
    int32 va_rawsize;  /* 原始数据大小(包括header) */
    int32 va_extsize;  /* 外部保存大小(不包括header) */
    Oid va_valueid;    /* TOAST表中值的唯一id */
    Oid va_toastrelid; /* toast表id */
} varatt_external;

其中va_extsize表示外部数据大小,va_rawsize表示原始未压缩数据大小,当且仅当va_extsize小于va_rawsize减var header大小时,数据会被压缩。

以上内容从段页式技术方面对GaussDB高弹性能力进行了解读,下篇将从hashbucket扩容方面继续介绍GaussDB高弹性技术,敬请期待! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2103712.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库审计是什么?主要用在哪些场景呢?

数据库审计是什么?主要用在哪些场景呢? 数据库审计 数据库审计是指对数据库系统中的操作进行记录、监控和分析的过程,用于检查和评估数据库的安全性、合规性和完整性。数据库审计可以为组织提供重要的安全保障和合规性需求的满足。本文将介…

嵌入式24千兆电口+4万兆光口管理型三层交换机RTL9301模块

核心模块概述: 嵌入式RTL9301模块可以支持4口万兆上联24口千兆三层管理型以太网交换机,也就是最多可以提供24个10/100/1000自适应电口、4个10 Gb SFP 端口、1个console口、1个USB串口。 完善的安全控制策略及CPU保护策略(CPU protect policy)提高容错能力&#xff0…

LLM大模型学习:LLM常见问题(思维链部分)

1. 什么是思维链提示? 思维链(Chain-of-thought,CoT),指的是一系列有逻辑关系的思考步骤,形成一个完整的思考过程。人在日常生活中,随时随地都会用思维链来解决问题,比如工作、读书经常用到的思维导图&…

【git】git安装方法

1 Git 的下载 这个就需要去 Git 官网下载对应系统的软件了,下载地址为 git-scm.com或者gitforwindows.org,或者阿里镜像(感谢评论区的星悸迷航同学) 上面的 git-scm 是 Git 的官方,里面有不同系统不同平台的安装包和…

Nhanes数据(复杂调查数据)绘制限制立方样条(rcs)函数svyggrcs1.8尝鲜版发布

临床上,因变量和临床的结局有时候不是线性关系,而回归模型有一个重要的假设就是自变量和因变量呈线性关联,因此非线性关系模型用回归分析来拟合受到限制。因此,一个更好的解决方法是拟合自变量与因变量之间的非线性关系&#xff0…

智慧公厕:城市公共卫生管理的新篇章‌@卓振思众

在快节奏的现代生活中,公共厕所作为城市基础设施的重要组成部分,其使用体验和管理效率直接影响着市民的生活质量与城市形象。随着科技的飞速发展,智慧公厕应运而生,它以一种全新的姿态,为城市公共卫生管理带来了前所未…

【吊打面试官系列-Redis面试题】Pipeline 有什么好处,为什么要用 pipeline?

大家好,我是锋哥。今天分享关于 【Pipeline 有什么好处,为什么要用 pipeline?】面试题,希望对大家有帮助; Pipeline 有什么好处,为什么要用 pipeline? 1000道 互联网大厂Java工程师 精选面试题…

ABAP 报错 提示 Use the associated entity XXX

警告,我们可以忽略,但是报错了,却不知道怎么改? 后面发现是 在ABAP里面 对CDS的字段做 substring 或者concat是不允许的

常见加解密算法06 - 分组密码的填充与工作模式

各位英姿焕发,风华正茂的读者们你们好啊,今天我们讨论一下分组密码的填充与工作模式。 分组密码中,需要将明文按指定大小进行分组,由于明文并非指定大小的整数倍,因此在明文的最后一个分组需要将其填充至加密算法所要…

向 ADC 模型和 DAC 建模添加低通滤波器

与单音测试信号相比,双音测试信号可提供更多有关 ADC 性能的信息。您的作者的模型与特定 ADC 的制造商模型非常匹配,因此可以方便地运行误码率模拟。该 ADC 恰好具有非常宽的输入带宽。 对于带宽较低的 ADC,添加如图 1 所示的低通滤波器将提…

[SUCTF 2018]annonymous1

知识点&#xff1a; 匿名函数创建其实有自己的名字&#xff08;%00lambda_%d&#xff09; 进入页面开始代码审计. <?php // 使用 create_function 创建一个匿名函数&#xff0c;该函数调用 die() 函数并执行 cat flag.php 命令&#xff08;在服务器上执行&#xff0c;如果…

BFF层聚合查询服务异步改造及治理实践

首先感谢王晓老师的[ 接口优化的常见方案实战总结]一文总结&#xff0c;恰巧最近在对稳健理财BFF层聚合查询服务优化治理&#xff0c;针对文章内的串行改并行章节进行展开&#xff0c;分享下实践经验&#xff0c;主要涉及原同步改异步的过程、全异步化后衍生的问题以及治理方面…

实训day42(9.3)

⼀、编排分类 单机容器编排: docker-compose 容器集群编排: docker swarm、mesosmarathon、kubernetes 应⽤编排: ansible(模块&#xff0c;剧本&#xff0c;⻆⾊) ⼆、系统管理进化史 1. 传统部署时代 早期&#xff0c;各个组织是在物理服务器上运⾏应⽤程序。 由于⽆法限…

Mac搭建音视频开发环境

1.安装软件 打开终端&#xff0c;依次输入如下命令&#xff1a; brew install ffmpeg brew install qt brew install --cask qt-creator 2.配置qt 打开Qt Creator&#xff0c;在首选项—>Qt版本设置qt路径 3.设置默认Kits 3.创建项目 输入项目名称和存放目录&#xff0c…

在国产芯片上实现YOLOv5/v8图像AI识别-【4.2】RK3588获取USB摄像头图像推流RTSP更多内容见视频

本专栏主要是提供一种国产化图像识别的解决方案&#xff0c;专栏中实现了YOLOv5/v8在国产化芯片上的使用部署&#xff0c;并可以实现网页端实时查看。根据自己的具体需求可以直接产品化部署使用。 B站配套视频&#xff1a;https://www.bilibili.com/video/BV1or421T74f 前言…

大屏适配各分辨率屏幕方案及整合动画性能

每个公司都不可避免会有一些数据可视化的需求&#xff0c;大数据时代&#xff0c;更是一发不可收拾&#xff0c;各种花里胡哨的大屏效果&#xff0c;让前端既烦恼又有些许刺激&#xff0c;刺激是新的挑战带来的&#xff0c;完成了各种风骚的展示效果&#xff0c;那种成就感让人…

荆州农商行资产质量下行压力不减,参股多家银行均有股权被冻结

撰稿|芋圆 2023年&#xff0c;湖北荆州农商行的业绩表现不佳&#xff0c;营收、利润双降。其中&#xff0c;2023年的营收6.8亿元&#xff0c;延续2022年的下滑趋势&#xff0c;同比降幅4.06%&#xff1b;利润总额2.2亿元&#xff0c;同比下滑15%&#xff1b;净利润1.8亿元&…

新疆火炬燃气安康杯知识竞赛活动策划方案

以赛促学&#xff0c;以学促安。为深入贯彻落实国家安全生产法律法规&#xff0c;增强公司员工的安全意识和法律素养&#xff0c;6月28日&#xff0c;新疆火炬燃气股份有限公司举办2024年安全生产法律法规“安康杯”知识竞赛。28支队提前抽好PK对手&#xff0c;两两PK&#xff…

Nginx 负载均衡+高可用 集群部署(Keepalived+LVS DR模式)

一、LVS负载均衡简介 1.1 LVS基本介绍 LVS&#xff08;Linux Virtual Server&#xff09;即Linux虚拟服务器&#xff0c;是由章文嵩博士主导开发的开源负载均衡项目&#xff0c;目前LVS已经被集成在Linux内核中。该项目在Linux内核中实现了基于IP地址的请求数据负载均衡调度方…

【C语言从不挂科到高绩点】09-作业练习-循环结构02

Hello!彦祖们,俺又回来了!!!,继续给大家分享 《C语言从不挂科到高绩点》课程,前面课程中给大家讲解了一些常规的知识点,那么本次课,我们一起来练习挑战一下!! 本套课程将会从0基础讲解C语言核心技术,适合人群: 大学中开设了C语言课程的同学想要专升本或者考研的同…