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单元
页面是GBase8s动态服务器中最基本的I/O单元;服务器进程不会以小于页面的增量读取或写入chunk。但是,尽可能频繁地一次对多个页面执行I/O。
机器的默认页面大小是2KB或4KB,具体取决于平台。您可以将每个dbspace的页面大小配置为2KB到16KB之间的任何值,但该值必须可以被默认页面大小整除。
在二进制级别上,系统中分配的每个页面都包含一个唯一的数据流。但这些数据的结构和含义总是基于少数几个模板。本文教您如何识别动态服务器页面之间的结构相似性,并破译这些结构的重要部分。这些技能可以帮助您理解GBase8s体系结构和行为,达到您从未想过的程度。
3、页面布局
页面布局整体分为:
- 页头
- 页主体
- 页尾
- 时间戳
- slot table
页头:
页头占据页面上的前24个字节。它包含页面的位置、类型和当前容量等信息。
时间戳:
每次修改页面时,位于页面最后4个字节的时间戳字段都会更新。时间戳可用于与其他页面进行比较,以确定哪个页面最近更新。
slot table:
插槽表使数据库服务器能够快速查找页面上的数据。它是一系列4字节的条目,从页面结束时间戳开始,并向页面开始处增长。表中的每个条目描述页面上的一个槽,该槽可以包含一个数据行或其他结构。槽表条目由两部分组成:槽的第一个字节的位置和槽的长度。槽表条目的作用就像一种指针,允许直接、随机地访问页面上的槽。
倾向于按顺序搜索的页面类型不使用槽表,尽管它们可以有槽表。逻辑日志页面是完全没有槽表的页面类型的一个示例。
页头的24个字节布局如下:
页头每个字段的详细解释:
元素 | 字节 | 描述 |
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的内部机制,提升数据库管理的效率和效果。