本节描述文件和目录级别的存储格式。
传统上,数据库集群使用的配置和数据文件都存储在集群的数据目录中,通常称为 PGDATA
(取自可用于定义它的环境变量的名称)。PGDATA
的常见位置是 /var/lib/pgsql/data
。同一机器上可以存在多个由不同服务器实例管理的集群。
PGDATA
目录包含几个子目录和控制文件,如表 65.1所示。除了这些必需的项之外,集群配置文件 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
/base
中都有一个子目录,以数据库在 pg_database
中的 OID 命名。此子目录是数据库文件的默认位置;特别是,它的系统目录存储在那里。
请注意,以下各节描述了内置 heap
表访问方法和内置 索引访问方法的行为。由于 PostgreSQL 的可扩展性,其他访问方法可能会以不同的方式工作。
每个表和索引都存储在单独的文件中。对于普通关系,这些文件以表或索引的filenode编号命名,该编号可以在 pg_class
.relfilenode
中找到。但是,对于临时关系,文件名采用 t
的形式,其中 BBB
_FFF
BBB
是创建该文件的后端进程号,FFF
是 filenode 编号。无论哪种情况,除了主文件(又名主分支)之外,每个表和索引都有一个空闲空间映射(请参见 第 65.3 节),它存储有关关系中可用空闲空间的信息。空闲空间映射存储在名为 filenode 编号加上后缀 _fsm
的文件中。表还有一个可见性映射,存储在后缀为 _vm
的分支中,用于跟踪已知没有死元组的页面。可见性映射在第 65.4 节中进一步描述。未记录的表和索引具有第三个分支,称为初始化分支,它存储在后缀为 _init
的分支中(请参见 第 65.5 节)。
请注意,虽然表的 filenode 通常与其 OID 匹配,但情况并非总是如此;某些操作(如 TRUNCATE
、REINDEX
、CLUSTER
和某些形式的 ALTER TABLE
)可以在保留 OID 的同时更改 filenode。避免假设 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
命令中指定的位置)。这个符号链接以表空间的 OID 命名。在物理表空间目录中,有一个子目录,其名称取决于 PostgreSQL 服务器版本,例如 PG_9.0_201008051
。(使用此子目录的原因是,数据库的后续版本可以使用相同的 CREATE TABLESPACE
位置值,而不会发生冲突。)在特定于版本的子目录中,对于在该表空间中具有元素的每个数据库,都有一个子目录,该子目录以数据库的 OID 命名。表和索引存储在该目录中,使用文件节点命名方案。pg_default
表空间不是通过 pg_tblspc
访问的,而是对应于 PGDATA
/base
。同样,pg_global
表空间不是通过 pg_tblspc
访问的,而是对应于 PGDATA
/global
。
pg_relation_filepath()
函数显示任何关系(relation)的完整路径(相对于 PGDATA
)。它通常可以作为记住上述许多规则的替代方法。但请记住,此函数仅提供关系主分支的第一个段的名称 — 您可能需要附加一个段号和/或 _fsm
、_vm
或 _init
才能找到与该关系关联的所有文件。
临时文件(用于排序超出内存容量的数据等操作)在 PGDATA
/base/pgsql_tmp
中创建,或者如果在为其指定的表空间不是 pg_default
的情况下,在表空间目录的 pgsql_tmp
子目录中创建。临时文件的名称具有 pgsql_tmp
的形式,其中 PPP
.NNN
PPP
是拥有后端的 PID,NNN
区分该后端的不同临时文件。
如果您在文档中发现任何不正确、与您使用特定功能的经验不符或需要进一步澄清的地方,请使用此表单报告文档问题。