# 23.6.表空间

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

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

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

# 警告

尽管表空间位于PostgreSQL主数据目录之外,但它是数据库集群和数据库的一个组成部分不能被视为数据文件的自动集合。它们依赖于主数据目录中包含的元数据,因此不能附加到其他数据库群集或单独备份。类似地,如果丢失了表空间(文件删除、磁盘故障等),数据库集群可能无法读取或无法启动。在临时文件系统(如RAM磁盘)上放置表空间会危及整个集群的可靠性。

要定义表空间,请使用创建表空间命令,例如::

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

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

# 笔记

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

表空间本身的创建必须以数据库超级用户的身份完成,但之后可以允许普通数据库用户使用它。要做到这一点,就给他们创造这是我的特权。

可以将表、索引和整个数据库分配给特定的表空间。要执行此操作,请使用创造给定表空间上的权限必须将表空间名称作为参数传递给相关命令。例如,下面的代码在表空间中创建一个表空间1:

CREATE TABLE foo(i int) TABLESPACE space1;

或者,使用违约_表空间参数:

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

什么时候默认表空间设置为空字符串以外的任何值,则提供隐式表空间条款创建表格创建索引没有显式命令的命令。

还有一个临时雇员_表空间参数,该参数确定临时表和索引以及用于排序大型数据集等目的的临时文件的位置。这可以是一个表空间名称列表,而不仅仅是一个,因此与临时对象关联的负载可以分布在多个表空间中。每次创建临时对象时,都会拾取列表中的随机成员。

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

初始化数据库集群时,会自动创建两个表空间。这个pg_全球表空间用于共享系统目录。这个pg_违约表空间是模板1模板0数据库(因此,也将是其他数据库的默认表空间,除非被表空间条款创建数据库).

一旦创建了表空间,只要请求用户有足够的权限,就可以从任何数据库使用表空间。这意味着在删除所有使用表空间的数据库中的所有对象之前,不能删除该表空间。

要删除空表空间,请使用删除表空间命令

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

SELECT spcname FROM pg_tablespace;

这个psql节目\分贝meta命令对于列出现有表空间也很有用。

PostgreSQL利用符号链接简化表空间的实现。这意味着可以使用表空间只有在支持符号链接的系统上。

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