Postgresql 中文操作指南
73.1. Database File Layout #
本部分从文件和目录的级别描述存储格式。
传统上,数据库群集中使用的配置和数据文件,都存储在群集的数据目录中,该目录通常称为 PGDATA(根据可用来定义该目录的环境变量的名称)。PGDATA 的常见位置是 /var/lib/pgsql/data。同一台机器上可以存在多个群集,由不同的服务器实例管理。
PGDATA_目录包含几个子目录和控制文件,如 Table 73.1中所示。除了这些必需项之外,群集配置文件 _postgresql.conf、_pg_hba.conf_和 _pg_ident.conf_传统上存储在 _PGDATA_中,尽管也有可能将它们放在其他地方。
Table 73.1. Contents of PGDATA
Item |
Description |
PG_VERSION |
包含 PostgreSQL 主要版本号的文件 |
base |
Subdirectory containing per-database subdirectories |
current_logfiles |
用于记录记录收集器当前写入日志文件的文件 |
global |
包含集群范围表(例如, pg_database )的子目录 |
pg_commit_ts |
包含事务提交时间戳数据的文件 |
pg_dynshmem |
包含动态共享内存子系统使用的文件的文件 |
pg_logical |
包含逻辑解码状态数据的文件 |
pg_multixact |
包含多事务状态数据(用于共享行锁)的文件 |
pg_notify |
包含 LISTEN/NOTIFY 状态数据的分目录 |
pg_replslot |
包含复制槽数据的子目录 |
pg_serial |
包含关于已提交的可序列化事务的信息的子目录 |
pg_snapshots |
Subdirectory containing exported 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 table access method和内置 index access methods的行为。由于 PostgreSQL 的可扩展特性,其他访问方法可能有所不同。
每个表和索引都存储在一个单独的文件中。对于普通关系,这些文件以表或索引的 filenode 编号命名,可以在 pg_class . relfilenode 中找到该编号。但对于临时关系,文件名采用 t_BBBFFF, where BBB 的形式,其中 t_BBBFFF, where BBB 是创建该文件的后端的后台 ID,而 FFF 是文件节点号。在任何一种情况下,除了主文件(也称为主分支)之外,每个表和索引都有一个 free space map (参见 Section 73.3 ),其中存储了有关关系中可用的可用空间的信息。可用空间映射存储在一个以文件节点号加上后缀 fsm 命名的文件中。表还有一个 visibility map ,存储在具有后缀 vm 的分支中,以跟踪哪些页面已知没有无效元组。可见性映射在 Section 73.4 中作了进一步描述。未记录的表和索引有一个称为初始化分支的第三个分支,该分支存储在一个以后缀 _init 为分叉中(参见 Section 73.5 )。
Caution
请注意,虽然表的 filenode 通常与它的 OID 匹配,但这 not 不一定是这种情况;某些操作(如 TRUNCATE、REINDEX、CLUSTER 和某些形式的 ALTER TABLE)可以改变 filenode 同时保留 OID。不要想当然地认为 filenode 和表 OID 相同。同时,对于某些系统目录(包括 pg_class 本身),pg_class.relfilenode 包含零。这些目录的实际 filenode 号存储在较低级别的数据结构中,并且可以使用 pg_relation_filenode() 函数获取。
当表或索引超过 1 GB 时,它将被分成 1GB 大小的 segments。第一个区段的文件名与 filenode 相同;后续区段分别命名为 filenode.1、filenode.2 等。这种安排避免了在具有文件大小限制的平台上出现问题。(实际上,1 GB 只是默认区段大小。在构建 PostgreSQL 时,可以使用配置选项 —with-segsize 调整区段大小。)原则上,空闲空间映射和可见性映射 fork 也可能需要多个区段,尽管在实践中不可能出现这种情况。
具有可能会包含较大条目的列的表将具有一个关联的 TOAST 表,该表用于将太大而无法放在表行中的字段值存储在外联机中。pg_class.reltoastrelid 从表(如果存在)链接至其 TOAST 表。有关详细信息,请参阅 Section 73.2。
表和索引的内容在 Section 73.6 中作了进一步讨论。
表空间使场景变得更加复杂。每个用户定义的表空间在 PGDATA/pg_tblspc_ 目录内都有一个符号链接,它指向物理表空间目录(即在表空间的 CREATE TABLESPACE 命令中指定的位置)。此符号链接以表空间的 OID 命名。在物理表空间目录内,有一个子目录,其名称取决于 PostgreSQL 服务器版本,例如 PG_9.0_201008051。(使用此子目录的目的是,以便数据库的后续版本可以使用同样的 CREATE TABLESPACE 位置值而不会发生冲突。)在特定于版本的子目录内,对于表空间中有元素的每个数据库,都有一个以数据库的 OID 命名。表和索引存储在该目录内,使用 filenode 命名方案。pg_default 表空间不是通过 pg_tblspc 访问的,而是对应于 PGDATA/base_。类似地,pg_global 表空间不是通过 pg_tblspc 访问的,而是对应于 PGDATA_/global_。
pg_relation_filepath() 函数显示任何关系的完整路径(相对于 PGDATA)。它通常可以用作记住上述许多规则的替代方法。但请记住,此函数仅提供关系主 fork 的第一区段的名称 — 你可能需要附加区段号和/或 fsm、vm 或 _init 以找到与关系相关的所有文件。
临时文件(用于诸如对超过内存容量的数据进行排序之类的操作)在 PGDATA /base/pgsql_tmp_ 中创建,或者如果为它们指定了 pg_default 以外的表空间,则在表空间目录的 pgsql_tmp 子目录中创建。临时文件的名称采用 pgsql_tmp_PPP .NNN 的形式,其中 _, where _PPP is the PID of the owning backend and NNN 区分该后端的不同临时文件。