服务器分页文件,数据库分页文件

本节提供一个在PostgreSQL表和索引使用的页格式的概述。

[1]

序列和TOAST表的格式就像一个普通表的。

下面说明一下,一个字节假定为包含8位。另外,术语项为存储在页上的一个独立数据值。

在表中,一项是一行;在索引中,一项为一个索引条目。

每个表和索引存储为固定大小的页数组。(通常 8 kB,不过当编译服务器的时候,可以选择不同的页大小)

在表中,所有的页是逻辑等价的,所以一个特殊项(行)可以存储在任意页。在索引,第一页通常保留为持有控制信息的元页,

这里可以有不同类型的索引页,依赖于索引访问方法。

Table 54-2显示一个页的整体布局,

这里每页有 5 部分。

Table 54-2. 页整体布局项描述页头数据24 字节 长整型。 包含关于页的一般信息,包含自由空间指针。

项ID数据指向实际项的(偏移量,长度)对的数组。

每项 4 字节。

自由空间未分配空间。从这个区域开始分配新项指针,或从结尾分配新项指针。

项实际项本身

专用空间索引访问方法专用数据。不同方法存储不同的数据。普通表里为空。

每页的前24个字节构成一个页头(PageHeaderData)。在Table 54-3有它的详细格式。前两个字段跟踪相关页的最近的WAL条目。

下边的一个2字节的字段是包含标志位。随后由3个2字节整数字段(pd_lower,pd_upper,

和 pd_special)。这些包含分别为从页开始到未分配空间的开始,到未分配空间的结束,专用空间的开始的偏移字节数。

下边页头的2字节,pd_pagesize_version,存储页大小和版本指示符。

从PostgreSQL 8.3开始 版本编号是 4;

PostgreSQL 8.1 和 8.2 使用版本编号 3;

PostgreSQL 8.0 使用版本编号 2;

PostgreSQL 7.3 和 7.4 使用版本编号 1;

先前发布版本使用版本编号 0。

(在大多数这些版本中,基本的页布局和头格式没有变化,但是堆布局有行头.)

页面大小是基本上只存在一个交叉检查;在安装的版本中,这里不支持多于一页大小的。最后一个字段是个提示,显示是否整理页,可能是有利的。

它跟踪在页上最旧的未修整的XMAX。

Table 54-3. 页头数据布局字段类型长度描述pd_lsnXLogRecPtr8 字节LSN: 该页上xlog日志记录变化的最后字节的下一字节

pd_tliuint162 字节最后变化的时间线ID(仅其最低16 位)

pd_flagsuint162 bytesFlag bits

pd_lowerLocationIndex2 bytesOffset to start of free space

pd_upperLocationIndex2 字节到自由空间结尾的偏移量

pd_specialLocationIndex2 字节到专用空间开始的偏移量

pd_pagesize_versionuint162 字节页大小和版本编号布局信息

pd_prune_xidTransactionId4 字节页上最旧的未修整的XMAX,如果没有则为零。

在src/include/storage/bufpage.h可以找到所有的详细信息。

下面的页头是项标识符(ItemIdData),每个需要4字节。一个项标识符包含一个到项开始的字节偏移,

以字节计的长度,和一些影响它解释的属性位。新项标识符需要从未分配空间的开始分配。

可以通过查看pd_lower来确定项标识符的数量,分配新的标示符,其会增加。因为一个项标示符从来不移动直到释放了它,

实际上,每个指针为PostgreSQL所创建的一项由页号和项标识符的索引构成。

(ItemPointer,还可以称为CTID)

项本身存储在从未分配的空间的结尾向后分配的空间。确切的结构取决于包含什么表。

表和序列两都使用一个名为HeapTupleHeaderData的结构,下面描述。

最后这段是"特殊段"其包含想存放的任何访问方法。例如,

b-tree 索引存储连接页左右的兄弟,以及相应的索引结构的一些其它数据。

普通的表根本没有使用特殊段。(通过设置pd_special等于页大小来表示)

所有表行结构方式相同。有个固定大小的头(在大多数机器占用23 字节),随后一个NULL位图的可选项,对象ID字段,和用户数据。

该头的详细信息在Table 54-4。

实际的用户数据(行中列)由 t_hoff 表示的偏移量开始,它必须始终是为平台的MAXALIGN间距的倍数。

NULL位图仅存在,如果在t_infomask设置了HEAP_HASNULL位。

如果它存在,它就开始于固定头的后面,占用足够的字节,每数据列一位。

(那是,t_natts 位一块) 在这个位列表中,

一个1位 标识非空,一个 0 位是空。

对象ID 仅存在,如果在t_infomask设置了HEAP_HASOID位。

如果存在,它将出现在t_hoff边界前。任何需要做 t_hoff 的MAXALIGN倍数的填充,出现在NULL位图和对象ID之间。

(反过来又保证对象ID得到恰当的对齐)

Table 54-4. HeapTupleHeaderData 布局字段类型长度描述t_xminTransactionId4 字节插入 XID 戳

t_xmaxTransactionId4 字节删除 XID 戳

t_cidCommandId4 字节插入 和/或 删除 CID 戳 (用 t_xvac 覆盖)

t_xvacTransactionId4 字节VACUUM 操作移动一行版本的XID

t_ctidItemPointerData6 字节这个当前的或新行版本的 TID

t_infomask2int162 字节字段个数,加上各种标志位

t_infomaskuint162 字节各种标志位数

t_hoffuint81 字节用户数据偏移量

在src/include/access/htup.h可以找到所有的详细信息。

解释实际数据只能从其它表获取信息来做,大多pg_attribute。

需要来表示字段位置的键值是attlen和attalign。

没有直接获取特定字段的方法,除仅当有固定宽度字段并且没有空值的情况外。所有这些策略封装在函数 heap_getattr, fastgetattr

和 heap_getsysattr。

要读取数据你需要逐次检查每个属性。首先检查字段是否为NULL依据 NULL位图。如果是,跳到下一个。

然后确定你已经右对齐。如果字段是固定宽度的字段,那么所有的字节简单的放置。如果它是变长的字段(attlen = -1)

那么它是一个更复杂的位。所有变长数据类型共享通用的头结构struct varlena,其包括存储值的总长度和一些标志位。

依赖这些标志,数据可能是行内或在一个TOAST表;它也可能是压缩的。

(参阅Section 54.2)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值