本节在文件和目录的层次上描述存储格式。
数据库集群所需要的所有数据都存储在集群的数据目录里,通常用环境变量 PGDATA 来引用。PGDATA 的一个常见值 /var/lib/pgsql/data 。不同服务器管理的多个集群,可以在同一台机器上共存。
PGDATA 目录包含几个子目录以及一些控制文件,在表52-1里面显示。除了这些必要的东西之外,集群的配置文件 postgresql.conf, pg_hba.conf, pg_ident.conf 通常也都存储在这里(PostgreSQL 8.0 之后也可以把它们放在别的地方)。
表52-1. PGDATA 的内容
Item | 描述 |
---|---|
PG_VERSION | 一个包含 PostgreSQL 主版本号的文件 |
base | 包含与每个数据库对应的子目录的子目录 |
global | 包含集群范围的表的子目录,比如 pg_database |
pg_clog | 包含事务提交状态数据的子目录 |
pg_multixact | 包含多重事务状态数据的子目录(用于共享的行锁) |
pg_subtrans | 包含子事务状态数据的子目录 |
pg_tblspc | 包含指向表空间的符号链接的子目录 |
pg_twophase | 包含用于预备事务的状态文件的子目录 |
pg_xlog | 包含 WAL(预写日志)文件的子目录 |
postmaster.opts | 一个记录服务器最后一次启动时使用的命令行参数的文件 |
postmaster.pid | 一个锁文件,记录着当前的服务器主进程 PID 和共享内存段 ID ,在服务器关闭之后此文件就不存在了。 |
对于集群里的每个数据库,在 PGDATA/base 里都有对应的一个子目录,子目录的名字是该数据库在 pg_database 里的 OID 。这个子目录是该数据库文件的缺省位置;特别值得一提的是,该数据库的系统表存储在此。
每个表和索引都存储在独立的文件里,以该表或者该索引的 filenode 号命名,该号码可以在 pg_class.relfilenode 找到。
警告 |
请注意,虽然一个表的 filenode 通常和它的 OID 相同,但实际上并不必须如此;有些操作,比如 TRUNCATE, REINDEX, CLUSTER 以及一些特殊的 ALTER TABLE 形式,都可以改变 filenode 而同时保留 OID 。不应该假设 filenode 和表 OID 相同。 |
在表或者索引超过 1 GB 之后,它就被分裂成 1GB 大小的段。第一个段的文件名和 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 。