Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

22.6. 表空间 #

PostgreSQL 中的表空间允许数据库管理员定义文件系统中的位置,以便存储代表数据库对象的那些文件。一旦创建,就可以在创建数据库对象时按名称引用表空间。

通过使用表空间,管理员可以控制 PostgreSQL 安装的磁盘布局。这至少在两个方面是有用的。首先,如果对群集进行初始化的分区或卷空间不足且无法扩展,则可以在其他分区上创建表空间并使用,直到可以重新配置系统。

其次,表空间允许管理员利用对数据库对象使用模式的了解以优化性能。例如,大量使用的索引可以放在非常快的高可用性磁盘上,例如昂贵的固态设备。同时,存储很少使用或对性能要求不高的已归档数据的表可以存储在较便宜、较慢的磁盘系统上。

警告

即使位于 PostgreSQL 主数据目录之外,表空间也是数据库群集的一个组成部分,并且 不能 被视为自治的数据文件集合。它们依赖于主数据目录中包含的元数据,因此无法附加到不同的数据库群集或单独备份。同样,如果您丢失了表空间(文件删除、磁盘故障等),则数据库群集可能无法读出或无法启动。将表空间放在临时文件系统(如 RAM 磁盘)上会让整个群集的可靠性面临风险。

要定义表空间,请使用 CREATE TABLESPACE 命令,例如:

CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';

位置必须是 PostgreSQL 操作系统用户拥有的现有空目录。稍后在表空间内创建的所有对象将存储在此目录下的文件中。此位置不能位于可移动或临时存储空间中,因为如果表空间丢失或缺失,则群集可能无法运行。

注意

在每个逻辑文件系统中创建多个表空间通常没有太多意义,因为您无法控制逻辑文件系统中各个文件的位置。但是,PostgreSQL 并没有强制执行此类限制,而且实际上它并不知道您系统上的文件系统边界。它只将文件存储在您告诉它使用的目录中。

创建表空间本身必须由数据库超级用户完成,但之后您可以允许普通数据库用户使用它。要做到这一点,请授予他们在表空间上有 CREATE 权限。

表、索引和整个数据库都可以分配到特定表空间。要做到这一点,在给定表空间上拥有 CREATE 权限的用户必须将表空间名称作为参数传递到相关命令。例如,以下示例在表空间 space1 中创建了一个表:

CREATE TABLE foo(i int) TABLESPACE space1;

或者使用 default_tablespace 参数

SET default_tablespace = space1;
CREATE TABLE foo(i int);

default_tablespace 设置为任意非空字符串时,它会为没有明确 TABLESPACE 子句的 CREATE TABLECREATE INDEX 命令提供一个隐含的 TABLESPACE 子句。

还有 temp_tablespaces 参数,它决定临时表和索引的位置以及用于对大型数据集排序等目的的临时文件的位置。这可以是表空间名称的列表,而不仅仅一个,以便与临时对象关联的负载可以分布到多个表空间。每当要创建一个临时对象时,就会从列表中随机选择一个成员。

与数据库关联的表空间用于存储该数据库的系统目录。此外,如果不提供 TABLESPACE 子句,并且没有其他选择由 default_tablespacetemp_tablespaces(如果合适)指定,那么它是用于在数据库中创建的表、索引和临时文件中的默认表空间。如果在未指定表空间的情况下创建数据库,则它将使用与从中复制模板数据库相同的表空间。

当数据库集群初始化时,自动创建两个表空间。 pg_global 表空间仅用于共享系统目录。 pg_default 表空间是 template1template0 数据库的默认表空间(并且因此,也将会是其他数据库的默认表空间,除非被 CREATE DATABASE 中的 TABLESPACE 子句覆盖)。

创建后,任何数据库都可以使用表空间,条件是请求用户具有足够的权限。这意味着只有当使用表空间的所有数据库中的所有对象都被删除后,表空间才能被删除。

要删除一个空表空间,请使用 DROP TABLESPACE 命令。

要确定现有表空间的集合,请检查 pg_tablespace 系统目录,例如

SELECT spcname FROM pg_tablespace;

psql 程序的 \db 元命令对列出现有表空间也很有用。

目录 $PGDATA/pg_tblspc 包含指向群集中定义的每个非内置表空间的符号链接。虽然不推荐,但可以通过重新定义这些链接来手动调整表空间布局。在没有情况下在服务器运行时执行此操作。请注意,在 PostgreSQL 9.1 及更早版本中,还需要使用新位置更新 pg_tablespace 目录。(如果不这样做,pg_dump 将继续输出旧的表空间位置。)