66.1. 数据库文件布局

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

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

PGDATA目录包含几个子目录和控制文件,如Table 66.1所示。除了这些必需项之外,群集配置文件postgresql.confpg_hba.confpg_ident.conf传统上存储在PGDATA中,尽管可以将它们放置在其他位置。

表 66.1. PGDATA 的内容

ItemDescription
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包含子 Transaction 状态数据的子目录
pg_tblspc子目录包含指向表空间的符号链接
pg_twophase包含准备好的 Transaction 的状态文件的子目录
pg_wal包含 WAL(预写日志)文件的子目录
pg_xact包含事务提交状态数据的子目录
postgresql.auto.conf用于存储由ALTER SYSTEM设置的配置参数的文件
postmaster.opts记录服务器上次启动的命令行选项的文件
postmaster.pid锁定文件,记录当前的 postmaster 进程 ID(PID),群集数据目录路径,postmaster 启动时间戳,端口号,Unix 域套接字目录路径(在 Windows 上为空),第一个有效的 listen_address(IP 地址或*;否则为空)侦听 TCP)和共享内存段 ID(服务器关闭后该文件不存在)

对于集群中的每个数据库,在PGDATA /base内都有一个子目录,该子目录以pg_database中数据库的 OID 命名。该子目录是数据库文件的默认位置。特别是其系统目录存储在此。

每个表和索引都存储在一个单独的文件中。对于普通关系,这些文件是以表或索引的* filenode 编号命名的,可以在pg_class中找到。 relfilenode。但是对于临时关系,文件名的格式为tBBB_FFF,其中 BBB 是创建文件的后端的后端 ID, FFF 是文件节点号。无论哪种情况,除了主文件(a/k/a 主分支)之外,每个表和索引都具有可用空间 Map*(请参见Section 66.3),该 Map 存储有关关系中可用空间的信息。可用空间 Map 存储在一个文件中,该文件的名称为 filenode 编号加上后缀_fsm。表格还具有可见性 Map,存储在带有后缀_vm的分支中,用于跟踪已知哪些页面没有死 Tuples。可见度图在Section 66.4中进一步描述。未记录的表和索引具有第三个分支,称为初始化分支,存储在带有后缀_init(请参见Section 66.5)的分支中。

Caution

请注意,尽管表的文件节点通常会匹配其 OID,但并非一定如此。某些操作(例如TRUNCATEREINDEXCLUSTER和某些形式的ALTER TABLE)可以在保留 OID 的同时更改文件节点。避免假定 filenode 和表 OID 相同。此外,对于某些系统目录,包括pg_class本身,pg_classrelfilenode包含零。这些目录的实际文件节点号存储在较低级别的数据结构中,可以使用pg_relation_filenode()函数获得。

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

包含可能具有较大条目的列的表将具有关联的* TOAST *表,该表用于离线存储字段值,这些字段值太大而无法正确保存在表行中。 pg_classreltoastrelid从表链接到其 TOAST 表(如果有)。有关更多信息,请参见Section 66.2

表和索引的内容将在Section 66.6中进一步讨论。

表空间使方案更加复杂。每个用户定义的表空间在PGDATA /pg_tblspc目录中都有一个符号链接,该链接指向物理表空间目录(即,表空间的CREATE TABLESPACE命令中指定的位置)。该符号链接以表空间的 OID 命名。在物理表空间目录中,有一个子目录,其名称取决于 PostgreSQL 服务器版本,例如PG_9.0_201008051。 (使用该子目录的原因是,连续的数据库版本可以使用相同的CREATE TABLESPACE位置值而不会发生冲突.)在特定于版本的子目录中,每个数据库都有一个子目录,该子目录在表空间中具有元素,以数据库的 OID。表和索引使用文件节点命名方案存储在该目录中。不能通过pg_tblspc访问pg_default表空间,但对应于PGDATA /base。类似地,不能通过pg_tblspc访问pg_global表空间,但对应于PGDATA /global

pg_relation_filepath()函数显示任何关系的完整路径(相对于PGDATA)。它通常可以用作记住许多上述规则的替代方法。但是请记住,此函数仅给出关系主分支的第一段的名称-您可能需要附加一个段号和/或_fsm_vm_init来查找与该关系关联的所有文件。

如果为临时文件指定了pg_default以外的表空间,则在临时表PGDATA /base/pgsql_tmp或表空间目录的pgsql_tmp子目录内创建临时文件(用于诸如对超出内存的数据排序的操作)。临时文件的名称格式为pgsql_tmpPPP.NNN,其中* PPP 是拥有的后端的 PID,而 NNN *区分该后端的不同临时文件。