1.OID-对象标识符类型
对象标识符类型Object Identifier Types ,内部使用,并作为系统表的主键;
别名类型对查找一个对象的OID非常方便
可以在用户定义的表中使用,但不推荐使用,万一行数超过了oid 的最大限制数(4 byte int),那就无法插入新行了。
oid不会添加到 用户自己创建的表里,除非指定 WITH OIDS 或者 default_with_oids 打开
oid2name 可以获取数据库、对象的OID
2.relfilenode-标识对象物理位置的数字标号
标识对象物理位置的数字标号,会随数据存放的位置变化而变化
函数 pg_relation_filenode() 可以获得对象的 relfilenode
OID 与relfilenode的关系
oid - 身份证号
refilenode - 户口本上户号
只要人的住址变了,户号就会变
truncate、vacuum full、删除重建表操作都会导致refilenode变化
postgres=# create table a(a int);
CREATE TABLE
postgres=# select oid,relfilenode from pg_class where relname='a';
oid | relfilenode
-------+-------------
16390 | 16390
(1 row)
postgres=# select pg_relation_filenode('a');
pg_relation_filenode
----------------------
16390
(1 row)
3.空闲空间映射(FSM)=FREE SPACE MAPPING
每一个表和索引(除了哈希索引)都有一个空闲空间映射(FSM)来保持对关系中可用空间的跟踪
伴随主关系数据被存储在一个独立的关系分支中,以关系的文件节点号加上一个_fsm后缀命名
FSM文件是执行VACUUM操作时,或者是为了插入行而第一次查询FSM文件时才会创建
PostgreSQL使用了树形结构组织FSM文件。FSM可以在数据插入时快速找到满足大小要求的空闲空间,从而复用空闲空间
4.可见性映射(VM)=visible mapping
为了能加快 VACUUM 清理的速度和降低对系统I/O性能的影响,V8.4版本以后为每个数据文件加了一个后缀为"__vm "的文件
每一个表都有一个可见性映射(VM)用来跟踪哪些页面只包含已知对所有活动事务可见的元组,
它也跟踪哪些页面只包含未被冻结的元组。它随着主关系数据被存储在一个独立的关系分支中,
以该关系的文件节点号加上一个_vm后缀命名有了这个文件后,通过VACUUM命令扫描这个 文件时,
如果发现VM文件中这个数据块上的位表示该数据块没有需要清理的行,
则会跳过对这个数据块的扫描,从而加快VACUUM清理的速度。
pg_visibility 模块可以被用来检查存储在可见性映射中的信息
FSM:方便分配空间。
VM:加快vacuum操作,跳过具有vm标识的块。
postgres=# select pg_relation_filepath('a'::regclass);
pg_relation_filepath
----------------------
base/13593/16390
(1 row)
postgres=# \! ls -l $PGDATA/base/13593/16390*
-rw-------. 1 pgsql pgsql 0 Mar 23 17:19 /postgresql/pgdata/base/13593/16390
5.物理结构:页结构
Page Header:Page的基本信息,指向空闲空间(free space),长为 24 bytes
ItemIdData(Row/Index Pointers)
一个记录偏移量/长度(offset/length)的数组,指向实际的记录(rows/index entries),每一个 item 4字节
Free Space:未分配的空间
新指针(pointers )从这个区域的开头开始分配
新的记录(rows/index entries)从结尾开始分配
Items(Row/Index Entry):实际的记录本身
Special:不同的索引访问方式相关的数据,在普通表中为空
6.物理结构-PageHeaderData 布局
域 类型 长度 描述
pd_lsn PageXLogRecPtr 8 bytes LSN: 最后修改这个页面的xlog记录最后一个字节后面的第一个字节
pd_checksum uint16 2 bytes 页面校验码
pd_flags uint16 2 bytes 标志位
pd_lower LocationIndex 2 bytes 到空闲空间开头的偏移量
pd_upper LocationIndex 2 bytes 到空闲空间结尾的偏移量
pd_special LocationIndex 2 bytes 到特殊空间开头的偏移量
pd_pagesize_version uint16 2 bytes 页面大小和布局版本号信息
pd_prune_xid TransactionId 4 bytes 页面上最老未删除 XMAX,如果没有则为0
postgres=# select txid_current();
txid_current
--------------
497
(1 row)
postgres=# insert into a values(1);
INSERT 0 1
postgres=# select xmin,xmax,cmin,cmax,ctid,a from a;
xmin | xmax | cmin | cmax | ctid | a
------+------+------+------+-------+---
498 | 0 | 0 | 0 | (0,1) | 1
xmin:当前事务ID;
xmax:毁灭事务ID
cmin:创建命令ID
ctid:PAGE/ITEM
postgres=# select xmin,xmax,cmin,cmax,ctid,a from a;
xmin | xmax | cmin | cmax | ctid | a
------+------+------+------+-------+----
498 | 0 | 0 | 0 | (0,1) | 1
499 | 0 | 0 | 0 | (0,2) | 2
500 | 0 | 0 | 0 | (0,3) | 3
501 | 0 | 0 | 0 | (0,4) | 4
502 | 0 | 0 | 0 | (0,5) | 10 #第五行。
7.物理结构-TUPLE 头部数据结构
域 类型 长度 描述
t_xmin TransactionId 4 bytes 插入XID标志
t_xmax TransactionId 4 bytes 删除XID标志
t_cid CommandId 4 bytes 插入和/或删除CID标志(覆盖t_xvac)
t_xvac TransactionId 4 bytes VACUUM 操作移动一个行版本的XID
t_ctid ItemPointerData 6 bytes 当前版本的TID或者指向更新的行版本
t_infomask2 uint16 2 bytes 一些属性,加上多个标志位
t_infomask uint16 2 bytes 多个标志位
t_hoff uint8 1 byte 到用户数据的偏移量
8.逻辑结构
一个PG Cluster是在同一个os上的一个或者多个PG database的集合
在一个操作系统(OS)中,可以有一个或者多个PG Cluster
不同的PG Cluster是以port (端口号)作为区分的
这两个PG Cluster的软件版本甚至可以是不同的软件版本
假设同一个OS上有两个PG Cluster,每个PG Cluster中均可以有一个名为database1的PG database
Cluster
Cluster,物理盘上的数据库存储区,在SQL标准中的术语为catalog cluster,在PostgreSQL中称之为database cluster,
它在PostgreSQL中从下述两个方面区分:
物理存储的绝对路径:$PGDATA
各自的端口号:5432
database:每个 PostgreSQL 服务可以包含多个独立的 database
表空间:PostgreSQL中的表空间实际是物理盘上的一个存储目录,它从下述两个方面进行区分:
表空间名:定义表空间时使用的路径(同一个路径,不能同时用于不同的表空间)
9.总结
(1)PageHead:页头包含如下信息:
LSN: 最后修改这个页面的xlog记录最后一个字节后面的第一个字节
页面校验码
标志位
到空闲空间开头的偏移量
到空闲空间结尾的偏移量
到特殊空间开头的偏移量
页面大小和布局版本号信息
页面上最老未删除 XMAX,如果没有则为0
(2)行头:TUPLE 包含的信息:
插入XID标志
删除XID标志
插入和/或删除CID标志(覆盖t_xvac)
VACUUM 操作移动一个行版本的XID
当前版本的TID或者指向更新的行版本
一些属性,加上多个标志位
多个标志位
到用户数据的偏移量