受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

22.6. 表空间 #

PostgreSQL中的表空间允许数据库管理员在文件系统中定义存放表示数据库对象的文件的位置。表空间一旦创建,在创建数据库对象时就可以通过名称引用它。

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

其次,表空间允许管理员利用对数据库对象使用模式的了解来优化性能。例如,一个使用非常频繁的索引可以放在速度非常快且高可用的磁盘上,例如昂贵的固态设备。同时,一个存放归档数据且很少使用或对性能并不关键的表,则可以放在成本更低、速度更慢的磁盘系统上。

Warning

即使位于 PostgreSQL 主数据目录之外,表空间仍然是数据库集簇不可分割的一部分,不能被视为一个独立的数据文件集合。它们依赖于主数据目录中的元数据,因此不能附加到不同的数据库集簇,也不能单独备份。同样,如果丢失一个表空间(文件被删除、磁盘故障等),数据库集簇可能会变得不可读或者无法启动。把表空间放在 RAM 磁盘这类临时文件系统上,会危及整个集簇的可靠性。

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

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

该位置必须是一个已经存在、为空并且由PostgreSQL操作系统用户拥有的目录。随后在这个表空间中创建的所有对象都会存储在该目录下的文件中。该位置不得位于可移动或瞬态存储上,因为如果表空间缺失或丢失,集簇可能无法正常工作。

Note

通常来说,在每个逻辑文件系统上创建多个表空间意义不大,因为你无法控制单个文件在一个逻辑文件系统中的具体位置。不过,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命令隐含地补上该子句。

还有一个temp_tablespaces参数,用来决定临时表和索引以及为大数据集排序等用途所使用的临时文件应放置在哪里。它可以是一个表空间名列表,而不只是单个表空间,这样与临时对象相关的负载就可以分散到多个表空间上。每次创建临时对象时,都会从该列表中随机挑选一个成员。

与数据库关联的表空间用于存储该数据库的系统目录。此外,如果没有给出TABLESPACE子句,并且default_tablespacetemp_tablespaces(视情况而定)也没有指定其他选择,那么它还是在该数据库中创建的表、索引和临时文件所使用的默认表空间。如果创建数据库时没有为其指定表空间,它将使用其所复制模板数据库的同一个表空间。

初始化数据库集簇时会自动创建两个表空间。pg_global表空间只用于共享系统目录。pg_default表空间是template1template0数据库的默认表空间(因此,除非被TABLESPACE子句覆盖,而该子句可在CREATE DATABASE中指定,否则它也会是其他数据库的默认表空间)。

表空间一旦创建,只要请求的用户具有足够权限,就可以从任何数据库中使用它。这意味着,只有当使用该表空间的所有数据库中的所有对象都已被移除之后,才能删除该表空间。

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

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

SELECT spcname FROM pg_tablespace;

还可以找出哪些数据库使用了哪些表空间;见Table 9.73psql程序的\db元命令对列出现有表空间也很有用。

$PGDATA/pg_tblspc目录包含符号链接,它们指向集簇中定义的每一个非内置表空间。虽然不推荐,但也可以通过重新定义这些链接来手工调整表空间布局。无论如何,都不要在服务器运行时执行此操作。注意,在 PostgreSQL 9.1 及更早版本中,还需要用新的位置更新 pg_tablespace 目录。(否则 pg_dump 将继续输出旧的表空间位置。)

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。