具有 Oracle 背景的用户认为表空间非常重要,并且惊讶于在 PostgreSQL 中找到的关于它们的信息如此之少。本文将解释它们是什么、它们何时有用以及是否应该使用它们。
什么是表空间
本质上,PostgreSQL 中的表空间是一个包含数据文件的目录。这些数据文件是具有状态的对象背后的存储:表、序列、索引和物化视图。在 PostgreSQL 中,每个这样的对象都有自己的数据文件。如果对象更大,它将有几个文件称为段,大小限制为 1GB。
PostgreSQL 使用操作系统的文件系统进行存储。这与 Oracle 不同,它本质上实现了自己的“文件系统”。
为了清楚起见,让我们比较一下这些术语:
Oracle 与 PostgreSQL 中的术语
| Oracle | PostgreSQL 或操作系统 |
|---|---|
| 表空间 | 文件系统 |
| 数据文件 | 逻辑/物理卷 |
| 部分 | 一个表的所有数据文件 |
| 程度 | 段/数据文件 |
默认表空间
每个 PostgreSQL 数据库集群最初都有两个表空间。你可以用\dbin列出它们psql:
List of tablespaces
Name | Owner | Location
------------+----------+----------
pg_default | postgres |
pg_global | postgres |
(2 rows)
你会发现没有指定位置,那是因为它们总是对应PostgreSQL数据目录的固定子目录:默认表空间( pg_default)是“ base”子目录,全局表空间( pg_global)是“ global”子目录。
默认情况下,所有数据文件都将存储在默认表空间中。只有某些对象存储在全局表空间:目录表pg_database,pg_authid,pg_tablespace并pg_shdepend和他们所有的索引。这些是所有数据库共享的唯一目录表。
创建和使用新表空间
要创建新表空间,您首先必须创建一个新目录。不要在 PostgreSQL 数据目录中创建该目录!
请注意,该目录必须属于“ postgres”操作系统用户(准确地说,该用户必须具有更改目录权限的权限)。
然后你可以创建表空间:
CREATE TABLESPACE mytbsp LOCATION '/tmp/mytbsp';
要使用表空间,您可以创建一个表或另一个包含存储的对象:
CREATE TABLE newtab (
id integer NOT NULL,
val text NOT NULL
) TABLESPACE mytbsp;
ALTER TABLE newtab
ADD CONSTRAINT newtab_pkey PRIMARY KEY (id)
USING INDEX TABLESPACE mytbsp;
CREATE INDEX newtab_val_idx ON newtab (val)
TABLESPACE mytbsp;
请注意,索引不会在与表相同的表空间中自动创建。
您还可以在表空间中创建数据库:
CREATE DATABASE newdb TABLESPACE mytbsp;
然后,在该数据库中创建的所有对象都将自动放置在该数据库的表空间中。
有一些ALTER命令可以更改任何对象的表空间。将对象移动到另一个表空间会复制数据文件,并且在移动对象时无法访问该对象。
备份和表空间
如果使用表空间对数据库执行文件系统备份,则必须备份所有表空间。您无法备份或恢复单个表空间,并且没有等同于 Oracle 的“可传输表空间”。
pg_basebackup使用纯格式将尝试将表空间保存在与数据库服务器相同的位置(该-D选项仅指定数据目录的位置)。要将数据从表空间备份到不同位置,您必须使用选项–tablespace-mapping=olddir=newdir。您可以对多个表空间多次使用此选项。
使用表空间使数据库管理更加复杂,因为数据目录不再包含所有数据。
我应该什么时候创建表空间?
在绝大多数情况下,您不应在 PostgreSQL 中创建额外的表空间。特别是,在与数据目录相同的文件系统或与另一个表空间相同的文件系统上创建表空间永远没有意义。
那么证明管理复杂性的表空间有什么好处呢?
- 如果数据分布在不同设备上的多个文件系统上,则可以分配 I/O 负载。但是,这可以通过在较低级别上进行条带化来同样或更好地完成。
- 如果磁盘空间不足,表空间将提供添加更多存储空间的选项。但是,通常使用某种描述的卷管理器在操作系统级别执行此操作。
- 如果要对数据库或表设置大小限制,可以将其放在大小有限的文件系统上的表空间中。
- 如果同时拥有快速、昂贵和慢速、廉价的存储,可以将需要良好性能的对象放在快速存储的单独表空间中。在这种情况下应该调整表空间上的seq_page_cost,random_page_cost和effective_io_concurrency选项以告诉优化器有关性能特征的信息。
- 如果希望在默认表空间以外的其他位置创建临时文件(用于临时表和查询处理),可以将该temp_tablespaces参数设置为不同的表空间。
如果在具有虚拟化存储的虚拟化环境中运行,那么除了第三点之外,所有这些都没有实际意义。由于如今几乎每个人都使用虚拟化,因此表空间正在成为越来越无关紧要的 PostgreSQL 功能。
破除一个古老的神话
在数据库管理员中流传着一个顽固的神话,即应该将表和索引放在不同的磁盘上以获得良好的性能。
你可能会听到人们就为什么在索引扫描期间访问模式的特定相互作用会使其在旋转磁盘上变得高效的详细争论。但是旋转磁盘正在停止工作,通常只会使用多个并发 SQL 语句来使存储系统饱和,但无论如何,所有此类访问模式都会中断。
神话背后的真相是,将 I/O 负载分散到多个设备上肯定是有益的。如果在操作系统级别使用条带化,与小心放置表和索引相比,将获得更好的分布。
结论
表空间在 PostgreSQL 中很少相关。抵制创建表空间并将所有数据保留在默认表空间中的诱惑。
原文地址:https://www.cybertec-postgresql.com/en/when-to-use-tablespaces-in-postgresql/?yw




