第 52 章 数据库物理存储
本章概述 PostgreSQL 数据库所使用的物理存储格式。
52.1. 数据库文件布局 #
本节从文件和目录的层次描述存储格式。
数据库集簇所需的全部数据都存放在集簇的数据目录中,该目录通常称为
PGDATA(名字来自可用于定义它的环境变量)。PGDATA 的一个常见位置是
/var/lib/pgsql/data。同一台机器上可以存在多个由不同服务器实例管理的集簇。
PGDATA 目录包含若干子目录和控制文件,如表 52.1所示。除这些必需项之外,集簇配置文件 postgresql.conf、pg_hba.conf 和 pg_ident.conf
传统上也存放在 PGDATA 中(不过在
PostgreSQL 8.0 及以后版本中,可以把它们放在其他地方)。
表 52.1. Contents of PGDATA
| Item | 描述 |
|---|---|
PG_VERSION | 包含 PostgreSQL 主版本号的文件 |
base | 包含每个数据库子目录的子目录 |
global | Subdirectory containing cluster-wide tables, such as
pg_database |
pg_clog | 包含事务提交状态数据的子目录 |
pg_multixact | 包含多事务状态数据的子目录(用于共享行锁) |
pg_subtrans | 包含子事务状态数据的子目录 |
pg_tblspc | 包含指向表空间的符号链接的子目录 |
pg_twophase | 包含预备事务状态文件的子目录 |
pg_xlog | Subdirectory containing WAL (Write Ahead Log) files |
postmaster.opts | 记录服务器上次启动时所用命令行选项的文件 |
postmaster.pid | 记录当前服务器 PID 和共享内存段 ID 的锁文件(服务器关闭后不存在) |
对于集簇中的每个数据库,PGDATA/base
中都有一个子目录,其名称是该数据库在 pg_database
中的 OID。这个子目录是该数据库文件的默认位置;特别是,它的系统目录就存放在这里。
每个表和索引都存储在单独的文件中,文件以表或索引的
filenode 编号命名,该编号可在
pg_class.relfilenode 中找到。
小心
请注意,虽然表的 filenode 往往与其 OID 相同,但这并非必然如此;有些操作,例如 TRUNCATE、REINDEX、CLUSTER 以及某些形式的
ALTER TABLE,会在保留 OID 的同时改变 filenode。不要假定 filenode 和表 OID 一定相同。
当表或索引超过 1 GB 时,会被划分成若干个 1 GB 大小的段。第一段的文件名与 filenode 相同,后续各段则命名为 filenode.1、filenode.2,依此类推。这样的安排避免了在文件大小受限的平台上出现问题。表和索引的内容将在第 52.3 节中进一步讨论。
如果一个表包含可能具有很大条目的列,它就会有关联的
TOAST 表,用于对那些大到无法直接保存在表行中的字段值进行线外存储。pg_class.reltoastrelid
会把该表关联到其 TOAST 表(如果存在的话)。更多信息见第 52.2 节。
表空间使情况变得更复杂。每个用户定义的表空间都在
PGDATA/pg_tblspc 目录中有一个符号链接,指向其物理表空间目录(即该表空间的 CREATE TABLESPACE
命令中指定的位置)。该符号链接以表空间的 OID 命名。在物理表空间目录中,对于每个在该表空间中拥有对象的数据库,都有一个以该数据库 OID 命名的子目录。表和索引就使用 filenode 命名方案存储在该目录中。pg_default 表空间不通过 pg_tblspc
访问,而是对应于 PGDATA/base。同样,pg_global 表空间也不通过
pg_tblspc 访问,而是对应于
PGDATA/global。