暂无图片
暂无图片
7
暂无图片
暂无图片
暂无图片

【GBase8s】 存储结构介绍和onspaces命令的实践案例

原创 遇见数据库 2023-05-31
2870

目录

GBase 8s 总体架构包含三个重要组成部分:处理器、共享内存和磁盘。今天我们详细来讲述磁盘部分的内容。整体架构如下图:

存储结构

首先,我们通过下图来认识 GBase 8s 存储结构的总体情况:

一个 GBase 8s 实例 Instance 可以创建多个 dbspaces,一个 dbspace 可以包含多个物理 chunks,一个 chunk 分成多个连续扩展区extents,一个表或者索引占用的空间被称为一个 tablespace,一个 extent 包含多个物理页 pages。其中,dbspace 、tablespace 和 extent 属于逻辑存储单元;chunk 和 page 属于物理存储单元。

1.1. 物理存储单元

chunk

chunk就是用于存储数据的连续磁盘空间(物理磁盘最大单元),是存储数据库数据的文件或者裸设备。一个chunk可以是一个裸设备(raw device)或者一个UNIX文件(cooked file)。一个chunk最大可以是4TB,最多可以有32767个chunk。

root chunk包含整个数据库保留页及系统表等信息。一般将物理日志、逻辑日志迁移到单独的dbspace上。root chunk存储格式如下图所示:


一个非root chunk主要存储表、索引的数据(Tablespace),划分为多个连续的extent。非root chunk的存储格式如下图所示:


sysadmin库中task()函数针对chunk有四种使用方法(同admin()函数):

1、设置可扩展:

EXECUTE FUNCTION task('modify chunk extendable',14);

其中,14是chunk ID,另外,如果不设置chunk为自动扩展,那么当chunk空间用完后,会自动新增一个chunk。

2、取消可扩展:

 EXECUTE FUNCTION task("modify chunk extendable off", "14");

3、手动扩展大小:

EXECUTE FUNCTION task("modify space expand", "testchunk1", "1000KB");

4、更改可扩展大小:

EXECUTE FUNCTION task("modify space sp_sizes", "dbspace3", "60000","10000", "100000");

extent

extent 就是物理上连续数据页的集合,tablespace(表和索引)的存储空间是以extent为单位来分配的。

如下图所示,在创建customer表时,数据库会根据extent size确定该表初始的空间,默认大小是8页。当向customer表中不断insert记录时,为表customer分配的空间将被使用完,此时,数据库需要为表扩展新的空间,GBase 8s以extent为单位进行扩展,我们可以用next size来指定表每次空间扩展的大小,默认大小也是8页,一个extent包含若干物理上连续的数据页。最大的extent数为32767。

下个示例为在testchunk3数据库空间上创建一个表t3 ,并指定extent size大小为20KB,next size大小为10KB:

CREATE TABLE t3 ( id int, name VARCHAR(20))
IN testchunk3
EXTENT SIZE 20
NEXT SIZE 10 ;

下图显示数据库服务器如何为扩展数据块分配 6 个页:

1、扩展数据块总是完全包含在一个块中;扩展数据块不能穿过块的边界。

2、如果数据库服务器找不到指定给下一个扩展数据块大小的连续磁盘空间,那么它将在数据库空间的下一个块中搜索连续的空间。

page

数据页Page是基本的存储单元,是最小的I/O单元,如下图所示。GBase 8s进行一次I/O的最小单元为一个page,即使我们只对一个page里的某一行记录进行了修改,GBase 8s也需要对整个数据页进行读取到内存和写入到磁盘。磁盘的一个数据页读取到内存就会分配一个同样大小的内存page来存储。GBase 8s支持不同大小的数据页:2kB、4kB、8kB、16kB。在大多数的UNIX系统中,缺省的数据页大小是2KB。

所有的数据库和系统信息被存储在数据页上,表的记录、索引的Index-key都以Page为存储单位进行存储管理。一个数据页的内部存储结构如下图所示,一个数据页总体上分成三部分:页头、页尾和数据部分。

对页头的解释如下。

数据页头总共占用24 Byte的空间, 由8个部分组成:

1、Page  Address :存储页的地址信息, 占用6 Byte ,由两部分组成:chunknum+pageoffsize

chunknum占用2 Byte,包含了符号位,故支持的最大chunk数为FFFF/2=32767,也就是说一个GBase 8s实例最多可以支持32767个chunk。

pageoffszie占用4 Byte ,故一个chunk的最大页数FFFFFFFF去掉符号位=2 的31 次方=2 billion,对于2k 的pagesize,最大的空间为4T=2的31次方*2K=2147483648*2k。

2、CHKSUM:校验位,占用2 Byte。

3、FLAG:标记位,占用2 Btye,标识该数据页存储的是表的数据(DATA)或者索引(BTREE)。

4、Nslots:记录数计数器,占用2 Byte ,记录该数据页总共存储的记录数。

5、Pfree :即Pointer of first free slots ,占用2 Byte ,用来指向页内第一个空闲的slots在页内的偏移值。

6、Nfree :number of free slots,占用2 Byte,页内总共空闲的slots数量。

7、Next Page:占用4 Btye,指向下页的地址,对于数据页为0,对于索引页则指向下一个节点。

8、Previous Page :占用4 Btye ,执行前页地址,对于数据页存储0,对于索引页则存储前页地址。

对页尾的解释如下:

数据页尾由两部分组成:时间戳和每个 slots 的描述信息。

1、timestamp:时间戳, 占用 4 Byte ,描述数据页的更新时间。

2、slots table:为 slots 描述信息,数据页中有多少 slots,则会对应多少个 slots bitmap,每个占用 4 Byte ,记录 slots 在页内的偏移地址和长度,当记录被删除时,只是将其中的占用长度设置为 0 ,在物理上并没有将记录信息清空。

对数据部分的解释如下:

1、在数据页中用来存储数据的部分可以存储行记录和索引key。

2、以 slots 的方式分成 n 个存储单元,每个 slots 存放一行记录或者一个 index-key。

3、在一个数据页中最多能存储 255 个slots。

1.2. 逻辑存储单元

dbspace

dbspace是一个或者多个chunk的逻辑集合存储单元,dbspace将数据库的逻辑存储单位table与物理存储单位chunk连接在一起,如下图所示。GBase 8s的内部设计支持一 个实例可以最多2047个dbspace,一个dbspace可以有1~32767个chunk。

dbspace 对整个 GBase 8s 实例可见,实例中的多个数据库都可以使用所有的dbspace, 可以指定 database 的默认 dbspace,创建表、索引时也可以指定所在的dbspace,对于分片表、索引可以同时使用多个dbspace。如下图所示。

按照 dbspace 的作用分类,在一个实际生产环境下的数据库系统中我们通常规划如下表所示的 dbspace。

dbspace 类型

rootdbs

也称为根目录,主要用来存储保留页及GBase 8s系统数据库的信息(sysmaster、sysadmin等)

plogdbs

物理日志文件所在的 dbspace

llogdbs

用来存储逻辑日志文件

tempdbs01

tempdbs02

tempdbs03

tempdbs04

用来存储临时表及排序和join需要的临时空间

Datadbs 01

Datadbs10

用来存储用户定义的表、索引数据,一般需要定义10~100个

Blobspaces

用于存储简单大对象(Simple Large Object,TEXT或BYTE类型的对象)的专门dbspace。blobspace中的基本存储单元是blobpage。blobpage的大小可被配置为数据库服务器的数据页(Page)大小的整数倍。对于blobspace里的数据,数据库服务器在将它们写回磁盘时不使用缓冲区(Buffer)

Sbspaces

用于存储智能大对象(smart large object,BLOB或CLOB类型的对象)的专门dbspace。Sbpage的大小与数据库服务器的数据页大小一样,不是可配置的。在缺省情况下,对sbspace的写操作是使用缓冲区(buffer)的。在创建sbspace时,用户可通过参数将sbspace配置成使用缓冲区或不使用缓冲区。

tablespace

tablespace 是一个逻辑概念,指一个表或者索引所占用的空间。GBase 8s 用tablespace 来描述一个表或者索引信息。一个tablespace是多个extent的逻辑集合,可以分布在不同的dbspace或者chunk上。在 GBase 8s 系统表中对表、索引采用 tablespace 进行描述。

GBase 8s 把分片表、索引的一个分片作为一个tablespace 进行管理。每个表、索引在GBase 8s 内部都有一个 partnum,在GBase 8s内部以该编号进行管理。例如在一个GBase 8s实例下有一个database tblspace,包含所有的数据库databases的信息。database tblspace 的partnum永远是0x00100002,位于 root dbspaces 上,也就是sysmaster数据中的sysdatabases表。

我们可以通过查询sysmaster的systabnames表得到一个数据库实例下的所有表、索引的tblspace信息。

1.3. 大对象存储

这里主要讲述GBase 8s大对象数据的磁盘存储结构和访问过程,按简单大对象和智能大对象分别进行介绍。

简单大对象

简单大对象的存储空间blobspaces,只能用来存储简单大对象数据(Text和Byte),blobspace是针对Text和Byte数据的特点进行了特殊设计的一种存储空间。GBase 8s使用不同的方法访问不同的存储空间数据。简单大对象(Text或者Byte)可以存储在dbspaces或者blobspaces中。

1、如果简单大对象存储在dbspace上,如下图所示,则简单大对象和其他字段作为一个整体存储在dbspace上,使用56 byte的描述符指向简单大对象。简单大对象写入磁盘的方法和普通表数据一致,即先将数据缓存在共享内存的buffer中,然后刷新到磁盘,同时,数据库需要记录简单大对象DML操作的物理、逻辑日志信息。

2、若将简单大对象数据存储在指定的 blobspace 上,则同样使用一个56 byte的指针指向大对象的存储位置信息。此时,数据库服务器不会使用不同的方法将简单大对象数据写入到磁盘上,而是通过虚拟段单独使用一个较小的缓存(Big buffer池)将数据直接、快速写入磁盘,类似light append方式,而不需要占用大量的buffer pool内存空间,从而可能将其他表或者索引从内存中挤出,所以该方式对系统的影响较小,写入速度较快,同时对checkpoint无影响。处于对性能的考虑,该方式也减少了逻辑、物理日志量,数据库也不将Text或者Byte数据的日志信息写入逻辑日志、物理日志文件。在备份逻辑日志时,直接将日志写入逻辑日志备份空间上,但是对简单对象的DML操作(insert、update、delete)将记录到逻辑日志中。如下图所示:

当将简单大对象存储在 blobspace 上时,对简单大对象数据的读、写过程将有别于普通的方式,如下图所示:

blobpage buffers是在GBase8s虚拟段中根据需要申请的用来缓存简单大对象数据blobpage的内存缓存。当从应用客户端接收简单的大对象数据时,数据库服务器端将创建一对blobspace buffers,一个用来读操作,另外一个用来写操作。每一个blobpage buffer的大小为一个blobspace blobpage的大小。每一个用户只能有一组blobspace buffers,因此,一个用户每次只能访问一个简单大对象。

简单大对象数据以1KB从客户端应用程序进程传送到数据库服务器端。数据库服务器将这1KB的信息填入blobspace buffers,当填满一个blobpages时,就指向下一个blobpage。而数据库服务器何时将第一个blobspace buffer写入磁盘是由用户定义的blobpage的大小决定的。例如:假设blobpage的大小为32KB,数据库服务器试图以32KB为增量读取或者写入数据。如果硬件环境(如磁盘控制器)不支持单个I/O操作完成32KB的数据量,则操作系统将内部循环多次来完成I/O请求。在创建该blobspace buffers的线程结束时,blobspace buffers才会被回收。

智能大对象

智能大对象(CLOB 和 BLOB)必须存储在Sbspaces上,智能大对象的存储结构和I/O行为由sbspace特性确定。如下图所示,sbspace的第一个chunk总是包含 3 个部分:元数据区域、用户数据区域和保留区,其他chunk可以共用第一个chunk的元数据区域。

元数据区域(MetaData Area)保存元数据标识sbspace的关键信息和存储在该sbspace上的每一个智能大对象,这样数据库服务器可以对智能大对象进行操作和恢复。

用户数据区域(UserData Area)保存用户定义的智能大对象数据,一个chunk可以有1~2个用户数据区域。

当元数据区域和用户数据区域需要更多空间时,可以从保留区(Reserved Area)进行分配,一个chunk可以有1~2个保留区。

智能大对象智能存储在sbspace中,通过ONCONFIG参数SBSPACENAME指定默认存储空间。可以通过put…in(sbspace)来指定存储空间,当指定多个空间时,将自动采用round-robin方式将数据均匀存储在多个空间上。如下图所示:

数据库服务器通过共享内存buffer pool来访问智能大对象数据,和存储在dbspaces上的数据一样。不过智能大对象中的用户数据部分的内存优先级较低,写入数据时,当一个buffer page被填满时,立即写入磁盘。如图所示。

对于 sbspace,也可以设置为不使用 buffer pool。

1.4. onspaces命令的使用

创建数据库空间

1. 创建dbspace,名称为dbspace1,路径/opt/dbs/dbs_chunk,大小1000KB:

touch dbs_chunk
chmod 660 dbs_chunk
chown gbasedbt:gbasedbt dbs_chunk
onspaces -c -d dbspace1 -p /opt/dbs/dbs_chunk -o 0 -s 1000

2、创建blobspace,名称为blobspace,路径/opt/chunk/blob_chunk,大小1000KB:

touch blob_chunk
chmod 660 blob_chunk
chown gbasedbt:gbasedbt blob_chunk
onspaces -c -b blobspace -g 2 -p /opt/chunk/blob_chunk -o 0 -s 1000

3、创建sbspace,名称为sbspace2,路径/opt/dbs/sbs_chunk,大小1000KB:

touch sbs_chunk
chmod 660 sbs_chunk
chown gbasedbt:gbasedbt sbs_chunk
onspaces -c -S sbspace2 -p /opt/dbs/sbs_chunk -o 0 -s 1000

删除数据库空间

可以使用 onspaces -d选项

1、删除dbspace,名称为dbspace1:

onspaces -d dbspace1 -y

注意:删除dbspace、blobspace时,删除时必须保证其空间不再使用,并且要事先删除存放在这个dbspace上的表,否则会返回一个错误信息。

2、删除sbspace:

onspaces -d -f sbs_chunk -y

注意:删除sbspace,加 -f 会强制删除包含用户数据和元数据的sbspace。

为dbspace增加chunk

1.向dbspace或blobspace添加chunk,chunk的路径为/opt/dbs/dbs_chunk1,大小为1000 KB

touch dbs_chunk1
chmod 660 dbs_chunk1
chown gbasedbt:gbasedbt dbs_chunk1
onspaces -a dbspace1 -p /opt/dbs/dbs_chunk1 -o 0 -s 1000

2.向sbspace添加chunk,chunk的路径为/opt/dbs/sbs_chunk1,大小为1000 KB:

touch sbs_chunk1
chmod 660 sbs_chunk1
chown gbasedbt:gbasedbt sbs_chunk1
onspaces -a sbspace2 -p /opt/dbs/sbs_chunk1 -o 0 -s 1000

从dbspace删除chunk

onspaces -d dbspace1 -p /opt/dbs/dbs_chunk1 -o 0

纸上得来终觉浅,绝知此事要躬行。大家一定要动动手敲一敲,用一用。O(∩_∩)O~

本文到这里就结束了,希望大家看完能学到自己想要的知识,国产数据库终将强大,GBASE作为其中的佼佼者,一定会再创辉煌,加油!

最后修改时间:2023-07-13 14:40:26
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论