ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 58.1\. 数据库文件布局 本节在文件和目录的层次上描述存储格式。 传统上,数据库集群所需要的配置和数据文件都存储在集群的数据目录里, 通常用环境变量`PGDATA`来引用。(用于定义它的环境变量名称之后) `PGDATA`的一个常见位值`/var/lib/pgsql/data`。 不同服务器实例管理的多个集群, 可以在同一台机器上共存。 `PGDATA`目录包含一些子目录和控制文件,在[Table 58-1](#calibre_link-2328)中显示。 除了这些必要的东西外,集群配置文件`postgresql.conf`, `pg_hba.conf`和 `pg_ident.conf`通常都存储在`PGDATA`这里。 (尽管PostgreSQL 8.0和之后版本中,有可能把它们放在其他地方)。 **Table 58-1\. `PGDATA`内容** | 项 | 描述 | | --- | --- | | `PG_VERSION` | 一个包含PostgreSQL主版本号的文件 | | `base` | 包含与每个数据库对应的子目录的子目录 | | `global` | 包含集群范围的表的子目录,比如`pg_database` | | `pg_clog` | 包含事务提交状态数据的子目录 | | `pg_multixact` | 包含多重事务状态数据的子目录(使用共享的行锁) | | `pg_notify` | 包含LISTEN/NOTIFY状态数据的子目录 | | `pg_serial` | 包含已提交可串行化事务信息的子目录 | | `pg_snapshots` | 包含输出快照的子目录 | | `pg_stat_tmp` | 包含临时文件的统计子系统的子目录 | | `pg_subtrans` | 包含子事务状态数据的子目录 | | `pg_tblspc` | 包含指向表空间的符号链接的子目录 | | `pg_twophase` | 包含用于预备事务的状态文件的子目录 | | `pg_xlog` | 包含WAL(预写日志)文件的子目录 | | `postmaster.opts` | 一个记录服务器最后一次启动时使用的命令行参数的文件 | | `postmaster.pid` | 一个锁文件, 记录着当前服务器主进程ID(PID),集群数据目录路径,服务器主起始时间戳,端口号, Unix-域套接目录路径(Windows上空),第一个有效listen_address(IP地址或者`*`, 如果不监听TCP,则为空),以及共享内存段ID, (在服务器关闭之后此文件就不存在了)。 | 对于集群里的每个数据库,在`PGDATA``/base`里都有对应的一个子目录, 子目录的名字是该数据库在`pg_database`里的OID。 这个子目录是该数据库文件的缺省位置;特别值得一提的是, 该数据库的系统表存储在此。 每个表和索引都存储在独立的文件里,对于普通关系,这些文件 以该表或者该索引的_filenode_号命名, 该号码可以在`pg_class`.`relfilenode`中找到。 但是对于临时性关系,文件名称形式`t``_BBB_`_`_FFF_`, 其中`_BBB_`是创建文件的后端ID,并且`_FFF_`是filenode号。 在任何情况下,除了主文件(a/k/a主叉文件), 每个表和索引有个_自由空间映射_(参阅[Section 58.3](#calibre_link-1512)), 其用来存储关于在关系中可用的自由空间的信息。 自用空间映射存储在文件名为filenode编号加上后缀`_fsm`的文件里。 表也有_可见映射_,存储在一个分叉文件,后缀为`_vm`, 用来跟踪那些已知没有死行的页, 该可见映射在[Section 58.4](#calibre_link-1513)进一步的描述。 未记录的表和索引有三分之一分支,被称之为初始化分支,使用后缀`_init` 存储在分支中(参阅[Section 58.5](#calibre_link-1514))。 | **Caution** | |:--- | | 请注意,虽然一个表的filenode通常和它的OID相同,但实际上并_不_必须如此; 有些操作,比如`TRUNCATE`, `REINDEX`, `CLUSTER` 以及一些特殊的`ALTER TABLE`形式, 都可以改变filenode而同时保留OID。避免假定filenode和表OID相同。 还有,对于某种系统表包括`pg_class`自身, `pg_class`.`relfilenode`包含零。 这些表的实际的filenode编号存储在低级别的数据结构, 并且可以使用`pg_relation_filenode()`函数获取。 | 在表或者索引超过1 GB之后,将分割成1GB大小的_段_。 第一个段的文件名和filenode相同; 随后的段名名为filenode.1, filenode.2 ... 等等。 这样的安排避免了在某些平台上的有文件大小限制的问题。 (实际上,1GB只是缺省的段大小。当构建PostgreSQL时, 可以使用配置选项`--with-segsize`调整段大小。) 原则上,自由空间映射和可见映射叉文件可能需要多个段, 尽管这在实践中不可能发生。 一个表如果有些字段里面可能存储相当大的数据, 那么就会有个相关联的_TOAST_表, 用于存储无法在表的数据行中放置的超大行外数据。 如果有的话,`pg_class`.`reltoastrelid` 从一个表链接到它的TOAST表。 参阅[Section 58.2](#calibre_link-80)获取更多信息。 表的内容和索引在[Section 58.6](#calibre_link-1172)中有讨论。 表空间把情况搞得更复杂些。 每个用户定义的表空间都在`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`) 替代记住许多上述规则,它往往是有用的。但是请记住, 这个函数只给了关系主分叉文件的第一部分的名称—你可能还需要一段 数字和/或`_fsm` or `_vm`用来找到关联该关系的所有文件。 创建临时文件(对于操作如更多数据于可适合内存的排序) 在`PGDATA``/base/pgsql_tmp`,或如果表空间不是指定的`pg_default`, 在表空间目录下的`pgsql_tmp`子目录。 临时文件的名表示为`pgsql_tmp``_PPP_`.`_NNN_`, 这里`_PPP_`是后台拥有的PID和`_NNN_`是后台来区分不同的临时文件。