本节介绍在文件和目录层级的存储格式。
传统上,数据库集群使用的配置和数据文件都一起存储在集群的数据目录中,这里一般称为 PGDATA
(根据可用于定义它的环境变量的名称)。PGDATA
的常见位置为 。同一台机器上可以有多个集群,由不同的服务器实例管理。
如 表 65.1 中所示,PGDATA
目录中包含多个子目录和控制文件。除了这些必需的项,集群配置文件 postgresql.conf
、pg_hba.conf
和 pg_ident.conf
一般存储在 PGDATA
中,但是也可以将它们放在其他地方。
表 65.1. PGDATA
的内容
项 | 说明 |
---|---|
PG_VERSION |
包含 PostgreSQL 主要版本号的文件 |
base |
包含每个数据库子目录的子目录 |
current_logfiles |
记录当前由日志收集器写入的日志文件 |
global |
包含集群范围表的子目录,例如 pg_database |
pg_commit_ts |
包含事务提交时间戳数据的文件 |
pg_dynshmem |
包含动态共享内存子系统使用的文件子目录 |
pg_logical |
包含逻辑解码状态数据的文件子目录 |
pg_multixact |
包含多事务状态数据(用于共享行锁)的子目录 |
pg_notify |
包含 LISTEN/NOTIFY 状态数据的子目录 |
pg_replslot |
包含复制槽数据的文件子目录 |
pg_serial |
包含已提交可序列化事务信息的文件子目录 |
pg_snapshots |
包含导出快照的子目录 |
pg_stat |
包含用于统计子系统的永久文件的文件子目录 |
pg_stat_tmp |
包含用于统计子系统临时文件的子目录 |
pg_subtrans |
包含子事务状态数据的文件子目录 |
pg_tblspc |
包含到表空间的符号链接的文件子目录 |
pg_twophase |
包含已准备事务状态文件的子目录 |
pg_wal |
包含 WAL(预写式日志)文件的子目录 |
pg_xact |
包含事务提交状态数据的文件子目录 |
postgresql.auto.conf |
用于存储由 ALTER SYSTEM 设置的配置参数的文件 |
postmaster.opts |
记录服务器上次启动时的命令行选项的文件 |
postmaster.pid |
记录当前 postmaster 进程 ID (PID)、集群数据目录路径、postmaster 启动时间戳、端口号、Unix 域名套接字路径(可能是空)、第一个有效的 listen_address(IP 地址或 * ,或者在不监听 TCP 时为空,以及共享内存段 ID(服务器关闭后此文件不存在)的锁定文件 |
集群中每个数据库都在 PGDATA
内有一个子目录,以 pg_database
中数据库的 OID 命名,名为 base
。此子目录是该数据库文件的默认位置;尤其是,其系统目录存储在那里。
请注意,以下各节介绍了内置 heap
的行为 表访问方法,以及内置 索引访问方法 的行为。由于 PostgreSQL 的可扩展特性,其他访问方法可能会有不同工作方式。
每个表和索引存储在单独文件中。对于普通关系,这些文件以表或索引的 文件节点 号码命名,可以在 pg_class
.relfilenode
中找到。但是对于临时关系,文件名格式为 t
,其中 BBB
_FFF
BBB
是创建该文件的后台进程号,FFF
是文件节点号。在这两种情况下,除了主文件(又称主叉)之外,每个表和索引都有一个 空闲空间图(参见 第 65.3 节),用于存储关于关系中可用空闲空间的信息。空闲空间图存储在名为文件节点号加后缀 _fsm
的文件中。表还有 可见性图,存储在后缀为 _vm
的叉中,用于追踪哪些已知没有无效元组的页。可见性图在 第 65.4 节 中有进一步描述。未记录的表和索引有一个第三个叉,称为初始化叉,存储在后缀为 _init
的叉中(参见 第 65.5 节)。
请注意,尽管表的文件节点通常与其 OID 匹配,但这种情况并非必然如此;某些操作(如 TRUNCATE
、REINDEX
、CLUSTER
和某些形式的 ALTER TABLE
)可以在保留 OID 的同时更改文件节点。切勿假设文件节点和表 OID 相同。此外,对于包括 pg_class
本身的特定系统目录,pg_class
.relfilenode
会包含零值。这些目录的实际文件节点号存储在较低级别的数据结构中,可使用 pg_relation_filenode()
函数获取该号码。
当表或索引超过 1 GB 时,它会被分割为千兆字节大小的段。第一个段的文件名称与文件节点相同;后续段被命名为 filenode.1、filenode.2 等。此安排避免了在文件大小受限的平台上出现问题。(实际上,1 GB 只是默认的段大小。在构建 PostgreSQL 时,可以使用配置选项 --with-segsize
调整段大小。)原则上,自由空间映射和可见性映射分支也可能需要多个段,尽管实际上不太可能发生这种情况。
具有可能包含大型条目的列的表将具有关联的TOAST表,该表用于对太大而无法保留在表行中的字段值进行非本机化存储。pg_class
.reltoastrelid
从表链接到其TOAST表格(如果存在)。有关更多信息,请参阅65.2 节。
在第 65.6 节中进一步讨论有关表和索引的内容。
表空间让场景更复杂。每个用户定义的表空间在PGDATA
/pg_tblspc
目录内都有一个符号链接,指向物理表空间目录(即,在表空间的CREATE TABLESPACE
命令中指定的位置)。此符号链接以表空间的 OID 命名。在物理表空间目录内,有一个子目录,其名称取决于PostgreSQL服务器版本,例如PG_9.0_201008051
。(使用此子目录的原因是,让数据库的连续版本可以使用相同的CREATE TABLESPACE
位置值,而不会产生冲突。)版本特定子目录内,为每个在表空间中具有元素的数据库都有一个子目录,以数据库的 OID 命名。表和索引存储在该目录内,使用文件节点命名方案。pg_default
表空间不是通过pg_tblspc
访问的,而是对应于PGDATA
/base
。类似地,pg_global
表空间不是通过pg_tblspc
访问的,而是对应于PGDATA
/global
。
pg_relation_filepath()
函数显示任何关系的完整路径(相对于PGDATA
)。它通常用作记住以上许多规则的替代。但是要注意,此函数仅给出关系的主分支的第一个段名称——您可能需要附加一个段号和/或_fsm
、_vm
或_init
才能找到与关系关联的所有文件。
临时文件(用于执行各种操作,例如对容量超过内存的数据执行排序),是在PGDATA
/base/pgsql_tmp
中创建的,或者如果为其指定了pg_default
以外的表空间,则是在表空间目录的pgsql_tmp
子目录中创建的。临时文件的名称形式为pgsql_tmp
,其中PPP
.NNN
PPP
所有者后端的 PID,NNN
区分该后端不同的临时文件。