In this series, we will deeply analyze the page structure of the GBase 8s database, helping database administrators and developers better understand its internal mechanisms.
1. Macroscopic Concepts
1) Page
A page is the most basic data storage unit on the IDS server side.
2) Extent
An extent is a combination of multiple physically contiguous pages (at least four). The storage space allocation for a database table is in units of extents.
3) Tbspace
A tbspace is a logical combination of extents. A tbspace consists of all extents allocated to a table. A tbspace can only exist in one dbspace but can span multiple chunks.
4) Chunk
A chunk is a piece of physical storage space allocated to the IDS server side, which can be a Unix file or a raw device.
5) Dbspace and Blobspace
A dbspace is a logical combination of chunks. A database administrator can create and add chunks to a dbspace, thereby increasing the database's storage space. When creating a dbspace, its primary chunk must be specified first.
2. Page: The Smallest I/O Unit
A page is the most basic I/O unit in the GBase 8s dynamic server. Server processes do not read or write chunks in increments smaller than a page. However, they perform I/O operations on multiple pages as frequently as possible.
The default page size of the machine is 2KB or 4KB, depending on the platform. You can configure the page size for each dbspace to any value between 2KB and 16KB, but this value must be divisible by the default page size.
At the binary level, each page allocated in the system contains a unique data stream. However, the structure and meaning of this data are always based on a few templates. This article will teach you how to recognize the structural similarities between dynamic server pages and decipher the important parts of these structures. These skills can help you understand the GBase 8s architecture and behavior to an extent you never imagined.
3. Page Layout
The page layout is divided into:
- Page Header
- Page Body
- Page Footer
- Timestamp
- Slot Table
Page Header
The page header occupies the first 24 bytes of the page. It contains information about the page's location, type, and current capacity.
Timestamp
Each time the page is modified, the timestamp field at the last 4 bytes of the page is updated. The timestamp can be used to compare with other pages to determine which page was updated most recently.
Slot Table
The slot table allows the database server to quickly locate data on the page. It is a series of 4-byte entries that grow from the end of the page timestamp toward the start of the page. Each entry in the table describes a slot on the page, which can contain a data row or other structure. Slot table entries consist of two parts: the position of the first byte of the slot and the length of the slot. Slot table entries act like pointers, allowing direct, random access to slots on the page.
Page types that tend to be searched sequentially do not use slot tables, although they can have slot tables. Logical log pages are an example of a page type without slot tables.
The layout of the first 24 bytes of the page header is as follows:
Detailed Explanation of Each Field in the Page Header:
Element | Bytes | Description |
---|---|---|
pg_offset | 4 | The position of the page in the chunk based on the page offset (starting from 0) |
pg_chunk | 2 | Chunk number (starting from 1) |
pg_cksum | 2 | Checksum used to check page consistency |
pg_nslots | 2 | Maximum number of active slots |
pg_flags | 2 | Page flag bits |
pg_frptr | 2 | Pointer to the byte after the last used slot on the page |
pg_frcnt | 2 | Number of available bytes |
pg_next | 4 | For index pages, this indicates the next node at the same level |
pg_prev | 4 | For index pages, this indicates the previous node at the same level |
1) pg_offset and pg_chunk
The pg_offset field contains the page offset, which indicates the physical position of the page in the chunk.
For each subsequent page in the chunk, the page offset value increases by 1. The pg_offset value of the first page in the chunk is 0. The maximum pg_offset value is based on the chunk's maximum value, approximately 4 TB.
The pg_chunk field contains the number of the chunk where the page is located. The chunk number starts from 1.
The combination of pg_chunk and pg_offset provides all the information needed to identify the page address. The maximum pg_chunk value is 32767.
2) pg_cksum
- The pg_cksum field stores the checksum used to verify page consistency.
- In non-secure versions, pg_cksum is related to pg_offset, pg_chunk, and timestamp.
- In secure versions (such as DB4J, SM, EAL4), for non-logical log pages, all fields except the 24-byte page header and the 4-byte timestamp at the page footer are checked; for logical log pages, the behavior is the same as in non-secure versions: pg_offset, pg_chunk, and timestamp are checked.
3) pg_nslots
- You might expect pg_nslots to equal the number of active (undeleted) slots on the page. However, pg_nslots actually represents the maximum number of active slots on the page.
- Even if slots are deleted, the pg_nslots field does not decrement. For example, if slots 1 to 4 out of a total of five slots are deleted for efficiency, slot 5 cannot become slot 1 because the row ID of the slot would change. Therefore, even if only one slot is active on the page, pg_nslots must remain at 5 to enable sequential scanning (ignoring row IDs), thereby searching far enough into the slot table.
- The maximum number of slots for a data page is 255.
4) pg_flags
The pg_flags field contains one or more page flags, represented by hexadecimal values logically "or-ed" together. Each bit's meaning is as follows:
-
0x0001
// Data page -
0x0002
// Partition page -
0x0004
// Free List page -
0x0008
// Chunk Free List page -
0x0009
// Remainder data page -
0x000a
// Reserved 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 physical log required -
0x4000
// Page altered in place -
0x8000
// B-tree leaf with DELFG's
5) pg_frptr and pg_frcnt
- The pg_frptr (free pointer) field points to the first free byte after all data on the page. If the last slot on the page is occupied, the free pointer points to the position after that slot.
- The pg_frcnt (free count) field is the total of all unused bytes on the page.
6) pg_next and pg_prev
- The last two 4-byte elements in the page header structure are not always filled. Their main purpose is as node pointers on index pages. On index pages (also called index nodes), these pointers contain the logical page numbers of the two adjacent nodes.
- The next pointer (pg_next) contains the logical page number of the right-hand node (containing higher key values), while the previous pointer contains the logical page number of the left-hand node (containing lower key values).
- The difference between physical and logical page numbers and the concept of right and left index nodes in a B+ tree will be explained in later modules.
- The next and previous pointer elements are designed as part of the page header structure for index pages. However, the eight bytes are not wasted in the headers of all non-index pages; other page types also use the next and previous pointers. For example, their use in logical log pages and tape head pages will be explained in later modules.
By deeply understanding the page structure of the GBase 8s database, database administrators and developers can more effectively perform database design, optimization, and troubleshooting. We hope this article helps you better grasp the internal mechanisms of GBase 8s, improving the efficiency and effectiveness of database management.