2024 年 9 月 26 日: PostgreSQL 17 发布!
支持版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

65.1. 数据库文件布局 #

本节描述了文件和目录级别的存储格式。

传统上,数据库集群使用的配置和数据文件存储在集群数据目录中,通常称为 PGDATA(以环境变量的名称命名,该变量可用于定义它)。PGDATA 的常见位置是 /var/lib/pgsql/data。同一台机器上可以存在多个由不同服务器实例管理的集群。

PGDATA 目录包含几个子目录和控制文件,如 表 65.1 所示。除了这些必需的项之外,集群配置文件 postgresql.confpg_hba.confpg_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/base 中都有一个子目录,以数据库在 pg_database 中的 OID 命名。此子目录是数据库文件的默认位置;特别是,它的系统目录存储在那里。

请注意,以下部分描述了内置 heap 表访问方法 和内置 索引访问方法 的行为。由于 PostgreSQL 的可扩展性,其他访问方法可能会有所不同。

每个表和索引都存储在单独的文件中。对于普通关系,这些文件以表或索引的 filenode 编号命名,可以在 pg_class.relfilenode 中找到。但是对于临时关系,文件名采用 tBBB_FFF 的形式,其中 BBB 是创建文件的后端的进程号,FFF 是 filenode 编号。无论哪种情况,除了主文件(又名主分支)之外,每个表和索引都有一个 空闲空间映射(参见 第 65.3 节),它存储有关关系中可用空闲空间的信息。空闲空间映射存储在一个以 filenode 编号加上后缀 _fsm 命名的文件中。表还具有一个 可见性映射,存储在具有后缀 _vm 的分支中,以跟踪哪些页面已知没有死元组。可见性映射在 第 65.4 节 中有更详细的说明。未记录的表和索引具有第三个分支,称为初始化分支,它存储在具有后缀 _init 的分支中(参见 第 65.5 节)。

注意

请注意,虽然表的 filenode 通常与其 OID 相匹配,但这并非总是如此;一些操作,如 TRUNCATEREINDEXCLUSTER 和某些形式的 ALTER TABLE,可以更改 filenode,同时保留 OID。避免假设 filenode 和表 OID 相同。此外,对于某些系统目录,包括 pg_class 本身,pg_class.relfilenode 包含零。这些目录的实际 filenode 编号存储在更低级别的结构中,可以使用 pg_relation_filenode() 函数获得。

当表或索引超过 1 GB 时,它将被划分为大小为千兆字节的 。第一个段的文件名与 filenode 相同;后续段分别命名为 filenode.1、filenode.2 等。这种安排避免了在具有文件大小限制的平台上出现问题。(实际上,1 GB 只是默认的段大小。在构建 PostgreSQL 时,可以使用配置选项 --with-segsize 调整段大小。)原则上,空闲空间映射和可见性映射分支也可能需要多个段,尽管这在实践中不太可能发生。

具有可能包含大条目列的表将具有一个关联的 TOAST 表,该表用于对太大而无法保存在表行中的字段值进行行外存储。 pg_class.reltoastrelid 从表链接到其TOAST表(如果有)。有关更多信息,请参见 第 65.2 节

第 65.6 节 中将进一步讨论表和索引的内容。

表空间使情况更加复杂。每个用户定义的表空间在 PGDATA/pg_tblspc 目录中都有一个符号链接,它指向物理表空间目录(即,在表空间的 CREATE TABLESPACE 命令中指定的 location)。此符号链接以表空间的 OID 命名。在物理表空间目录内,有一个子目录,其名称取决于 PostgreSQL 服务器版本,例如 PG_9.0_201008051。(使用此子目录的原因是,数据库的后续版本可以使用相同的 CREATE TABLESPACE location 值,而不会出现冲突。)在特定于版本的子目录内,每个数据库都有一个子目录,该数据库在表空间中具有元素,以数据库的 OID 命名。表和索引存储在该目录中,使用 filenode 命名方案。 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_tmpPPP.NNN 的形式,其中 PPP 是拥有后端的 PID,NNN 区分该后端的不同临时文件。

提交更正

如果您在文档中发现任何错误、与您对特定功能的体验不符或需要进一步澄清,请使用此表格报告文档问题。