Skip to content

23.6. 表空间#

PostgreSQL中的表空间允许数据库管理员定义文件系统中的位置,其中可以存储表示数据库对象的那些文件。创建后,在创建数据库对象时,可以通过名称来引用表空间。

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

其次,表空间允许管理员利用数据库对象使用模式的知识来优化性能。例如,可以将使用非常频繁的索引放在非常快速、高可用性的磁盘上,例如昂贵的固态设备。同时,存储很少使用或对性能不重要的存档数据的表可以存储在不太昂贵、较慢的磁盘系统上。

警告

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

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

CREATE TABLESPACE fastspace LOCATION '/ssd1/guide/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将继续输出旧的表空间位置。)