GBase8s页结构_01_页结构详解,本系列文章将深入解析GBase 8s数据库的页结构,帮助数据库管理员和开发者更好地理解其内部机制。

1、宏观概念

1)page
page是ids服务端的最基本数据存储单位。

2)extent
extent是多个物理连续page(最少4个)的组合。数据库表的存储空间分配是以extent为单位的。

3)tbspace
tbspace是extent的逻辑组合。tbspace由分配给一个表的所有extent组成。一个tbspace只可能在一个dbspace中,但可能跨越多个chunk。

4)chunk
chunk是分配给ids服务端的一块物理存储空间,可以是unix文件,也可以是原始设备。

5)dbspace、blobspace
dbspace是chunk的逻辑组合。数据库管理员可以为dbspace创建、增加chunk,从而增加数据库的存储空间。创建dbspace时必须首先指定它的primary chunk。

2、 页:最小的IO单元

南大通用GBase 8s数据库的页结构详解-01_字段

页面是GBase8s动态服务器中最基本的I/O单元;服务器进程不会以小于页面的增量读取或写入chunk。但是,尽可能频繁地一次对多个页面执行I/O

机器的默认页面大小是2KB或4KB,具体取决于平台。您可以将每个dbspace的页面大小配置为2KB到16KB之间的任何值,但该值必须可以被默认页面大小整除。

在二进制级别上,系统中分配的每个页面都包含一个唯一的数据流。但这些数据的结构和含义总是基于少数几个模板。本文教您如何识别动态服务器页面之间的结构相似性,并破译这些结构的重要部分。这些技能可以帮助您理解GBase8s体系结构和行为,达到您从未想过的程度。

3、页面布局

南大通用GBase 8s数据库的页结构详解-01_8s_02

页面布局整体分为:

  • 页头
  • 页主体
  • 页尾
  • 时间戳
  • slot table

 

页头:

页头占据页面上的前24个字节。它包含页面的位置、类型和当前容量等信息。

时间戳:

每次修改页面时,位于页面最后4个字节的时间戳字段都会更新。时间戳可用于与其他页面进行比较,以确定哪个页面最近更新。

slot table:

插槽表使数据库服务器能够快速查找页面上的数据。它是一系列4字节的条目,从页面结束时间戳开始,并向页面开始处增长。表中的每个条目描述页面上的一个槽,该槽可以包含一个数据行或其他结构。槽表条目由两部分组成:槽的第一个字节的位置和槽的长度。槽表条目的作用就像一种指针,允许直接、随机地访问页面上的槽。

倾向于按顺序搜索的页面类型不使用槽表,尽管它们可以有槽表。逻辑日志页面是完全没有槽表的页面类型的一个示例。

页头的24个字节布局如下:

南大通用GBase 8s数据库的页结构详解-01_时间戳_03

 

页头每个字段的详细解释:

 

元素

字节

描述

pg_offset

4

基于页面偏移量的页面在chunk中的位置(从0开始)

pg_chunk

2

chunk 号(从1开始)

pg_cksum

2

用于检查页面一致性的checksum

pg_nslots

2

活动slot的最大数量

pg_flags

2

页标志位

pg_frptr

2

指向页面上最后一个使用的slot后的字节

pg_frcnt

2

可用字节数

pg_next

4

对于索引页,这表示同一级别的下一个节点

pg_prev

4

对于索引页,这表示同一级别的上一个节点

 

1)pg_offset 和 pg_chunk

pg_offset字段包含页面偏移量,该偏移量指示页面在chunk中的物理位置。

对于chunk中的每个后续页面,页面偏移量值增加1。chunk中的第一个页面的pg_offset值为0。最大pg_offset值基于chunk的最大值,大约为4 TB

pg_chunk字段包含页面所在chunk的编号。chunk编号从1开始。

pg_chunk和pg_offset的组合提供了标识页面地址所需的所有信息。最大pg_chunk值为32767

2)pg_cksum

  • pg_cksum字段存储用于验证页面一致性的校验和值。
  • 在非安全版的情况下,pg_cksum和pg_offset, pg_chunk,时间戳相关。
  • 在安全版(比如DB4J, SM, EAL4)的情况下,
  • 对于非逻辑日志页,除了页头24字节和页尾4字节时间戳,都校验。
  • 对于逻辑日志页,和非安全版一致,校验pg_offset, pg_chunk和时间戳。

3)pg_nslots

  • 您可能希望pg_nslots等于页面上活动(未删除)插槽的数量。但实际上,pg_nslots表示页面上活动插槽的最大数量。
  • 即使删除了插槽,pg_nslots字段也不会递减。以数据页为例。如果删除了总共五个slot中的slot1到4,则为了空间效率,slot 5不能成为slot1,因为该slot的rowid将改变。即使此时页面上只有一个slot处于活动状态,pg_nslots必须保持为5,以启用顺序扫描(不关心行ID),从而在slot表中搜索足够远的位置。
  • 数据页的最大插槽数为255。

4)pg_flags

pg_flags字段包含一个或多个页面标志,这些标志由逻辑上进行“或”运算的十六进制值表示。每个bit的含义如下表:
0x0001        // Data page
0x0002        // Partition page
0x0004        // Free List page
0x0008        // Chunk Free List page
0x0009        // Remainder data page
0x000a        // Being reserver for compression feature
0x000b        // Partition resident BLOB page
0x000c        // BlobSpace resident BLOB page
0x000d        // Blob Chunk Free List Bit page
0x000e        // Blob Chunk Blob Map Page
0x0010        // B-tree node page
0x0020        // B-tree root node
0x0040        // B-tree twig node
0x0080        // B-tree leaf node
0x0100        // Logical Log page
0x0200        // Last Page of logic Log
0x0400        // Sync Page of logic Log
0x0800        // Page in BigChunk Format
0x1000        // Reserved Root Pages
0x2000        // No phys log required
0x4000        // Page altered in place
0x8000        // B-tree leaf w/DELFG's

5)pg_frptr 和 pg_frcnt

  • pg_frptr(自由指针)字段指向页面上所有数据之后的第一个自由字节。如果页面上的最后一个slot被占用,则空闲指针指向该slot之后的位置。
  • pg_frcnt(空闲计数)字段是页面上所有未使用字节的总和。

6)pg_next 和 pg_prev

  • 页首结构中的最后两个4字节元素并不总是填充的。它们的主要用途是作为索引页上的节点指针。在索引页(也称为索引节点)上,这些指针包含两个相邻节点的逻辑页码。
  • 下一个指针(pg_next)包含右侧节点的逻辑页码(包含较高的键值),而上一个指针包含左侧节点的逻辑页数(包含较低的键值)。
  • 物理和逻辑页码之间的区别,以及右索引节点和左索引节点的B+树概念,将在后面的模块中解释。
  • 下一个和上一个指针元素被设计成页眉结构,用于索引页。但是,并没有在所有非索引页面的标题中浪费八个字节,而是在其他一些页面类型中找到了下一个和上一个指针的用法。例如,它们在逻辑日志页和磁带头页中的使用将在后面的模块中进行说明。

通过深入理解GBase 8s数据库的页结构,数据库管理员和开发者可以更有效地进行数据库设计、优化和故障排查。希望本文能够帮助您更好地掌握GBase 8s的内部机制,提升数据库管理的效率和效果。