73.1. 数据库文件布局#
本节描述了文件和目录级别的存储格式。
传统上,数据库集群使用的配置和数据文件存储在集群的数据目录中,通常称为PGDATA
(以可用于定义它的环境变量的名称命名)。PGDATA
的常见位置是/var/lib/pgsql/data
。由不同服务器实例管理的多个集群可以在同一台机器上存在。
如表 73.1所示,PGDATA
目录包含多个子目录和控制文件。除了这些必需项之外,集群配置文件postgresql.conf
、pg_hba.conf
和pg_ident.conf
通常存储在PGDATA
中,尽管可以将它们放在其他位置。
表 73.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 | 记录当前后端进程 ID (PID)、集群数据目录路径、后端进程启动时间戳、端口号、Unix 域套接字目录路径(可能为空)、第一个有效的 listen_address(IP 地址或 * ,如果未在 TCP 上侦听则为空)和共享内存段 ID 的锁定文件(服务器关闭后此文件不存在) |
集群中每个数据库在PGDATA``/base
中都有一个子目录,其名称以pg_database
中数据库的 OID 命名。此子目录是数据库文件的默认位置;特别是,其系统目录存储在此处。
请注意,以下部分描述了内置heap
表访问方法和内置索引访问方法的行为。由于PostgreSQL的可扩展性,其他访问方法可能工作方式不同。
每个表和索引存储在单独的文件中。对于普通关系,这些文件以表或索引的文件节点编号命名,该编号可以在pg_class
.relfilenode
中找到。但对于临时关系,文件名采用t*
BBB*_*
FFF*
的形式,其中*BBB
是创建该文件的后端的 ID,FFF
是文件节点编号。在任何一种情况下,除了主文件(又称主分支)外,每个表和索引都有一个空闲空间映射*(请参见第 73.3 节),其中存储有关关系中可用空闲空间的信息。空闲空间映射存储在以文件节点编号加上后缀_fsm
命名文件中。表还具有可见性映射,存储在具有后缀_vm
的分支中,以跟踪已知不包含无效元组的页面。可见性映射在第 73.4 节中进一步描述。未记录的表和索引具有第三个分支,称为初始化分支,该分支存储在具有后缀_init
的分支中(请参见第 73.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表。有关详细信息,请参见第 73.2 节。
表和索引的内容在第 73.6 节中进一步讨论。
表空间使场景更加复杂。每个用户定义的表空间在PGDATA``/pg_tblspc
目录中都有一个符号链接,该链接指向物理表空间目录(即,在表空间的CREATE TABLESPACE
命令中指定的路径)。此符号链接以表空间的 OID 命名。在物理表空间目录中,有一个子目录,其名称取决于PostgreSQL服务器版本,例如PG_9.0_201008051
。(使用此子目录的原因是,数据库的连续版本可以使用相同的CREATE TABLESPACE
位置值而不会发生冲突。)在特定于版本的子目录中,为具有表空间中元素的每个数据库有一个子目录,以数据库的 OID 命名。表和索引存储在该目录中,使用 filenode 命名方案。无法通过pg_tblspc
访问pg_default
表空间,但它对应于PGDATA``/base
。同样,无法通过pg_tblspc
访问pg_global
表空间,但它对应于PGDATA``/global
。
pg_relation_filepath()
函数显示任何关系的完整路径(相对于PGDATA
)。它通常可作为记住上述许多规则的替代方法。但请记住,此函数仅给出关系主分支的第一个段的名称——您可能需要附加段号和/或_fsm
、_vm
或_init
来查找与关系关联的所有文件。
临时文件(用于执行诸如对超出内存容量的数据进行排序之类的操作)在PGDATA``/base/pgsql_tmp
中创建,或者在为其指定pg_default
以外的表空间的情况下,在表空间目录的pgsql_tmp
子目录中创建。临时文件的名称格式为pgsql_tmp*
PPP*.*
NNN*
,其中*PPP
是拥有后端的 PID,NNN
*区分该后端的不同临时文件。