1、什么是PG中的表空间(tablespace)?
pg中的表空间实际上就是文件系统中的一个目录, 是pg中数据库对象(包括表、索引等)的容器。
Pg使用操作系统的文件系统进行对象存储,每个数据库对象都有自己的数据文件,如果对象很大,它将会被分为多个文件,单个文件大小的上限是1GB。表空间就是包含这些数据文件的目录。
简而言之,表空间是告诉PG服务器将数据库对象的物理文件放在哪里。
2、表空间的分类?
默认表空间:pg_default ,是用户表、用户表index、和临时表、临时表index、内部临时表的默认空间。对应文件系统目录$PADATA/base/。
系统字典表表空间:pg_global,存放系统字典表,如pg_database、pg_authid、pg_tablespace等表以及它们的索引。对应文件系统目录$PADATA/global/。
自定义表空间:用户创建的表空间。对应文件系统目录$PADATA/pg_tblspc/, 当手动创建表空间时,该目录下会自动生成一个软链接,指向表空间设定的路径。
其中pg_default和pg_global是在PG集群initdb之后默认创建的。
3、查看当前集群中所有的表空间?
PSQL使用"\db+"命令,可以详细列出表空间。
postgres=# \db+
List of tablespaces
Name | Owner | Location | Access privileges | Options | Size | Description
------------+-------+-------------+-------------------+---------+---------+-------------
pg_default | root | | | | 22 MB |
pg_global | root | | | | 573 kB |
mytbsp |root | tmp/mytbsp | | | 0 bytes |
其中mytbsp是用户自己创建的表空间。
查看pg_tblspc目录下,发现有一个软链接16385(16385是这个表空间的OID), 指向表空间设定的路径,此处为/tmp/mytbsp
/tmp$ ls -l data/pg_tblspc
total 0
lrwxrwxrwx 1 alice alice 11 May 8 11:47 16385 -> tmp/mytbsp
也可以使用sql查看所有表空间:
select oid,* from pg_tablespace;
4、表空间的创建和使用?
1)要创建表空间,首先创建一个新目录,注意该目录需要属于“postgres”操作系统用户。
2)使用sql创建表空间。
CREATE TABLESPACE mytbsp LOCATION '/tmp/mytbsp';
3)使用表空间。
大多数“create” SQL命令都带有一个“TABLESPACE”选项,我们可以使用这个选项指定SQL对象的表空间。
如:
在表空间mytbsp中创建一个名为testdb的数据库。注:此后该数据库中所有对象的默认表空间也成为mytbsp。
create database testdb tablespace mytbsp;
在mytbsp表空间中创建一个表newtab。
CREATE TABLE newtab (id integer NOT NULL,val text NOT NULL) TABLESPACE mytbsp;
注意:索引并不会继承与表的表空间。
在mytbsp表空间中创建索引对象。
CREATE INDEX newtab_val_idx ON newtab (val)TABLESPACE mytbsp;
另外,ALTER命令可以更改任何对象的表空间。
更改newtab的表空间为pg_default。
alter table newtab set tablespace pg_default;
我们也可以将一个表空间中的所有表(或索引)都移动到另外一个表空间。
alter table all in tablespace mytbsp set tablespace pg_default;
注意:将对象移动到另一个表空间将复制数据文件,在这个期间涉及到的对象将被锁定,不可访问。
5、含有自定义表空间的集群的备份?
如果对包含表空间的数据库执行文件系统备份,则必须备份所有表空间。
使用普通格式的pg_basebackup将尝试将表空间保存在与数据库服务器上相同的位置(-D选项仅指定数据目录的位置)。要将数据从表空间备份到不同的位置,必须使用选项--tablespace-mapping=olddir=newdir。对于多个表空间,可以多次使用此选项。
pg_basebackup --format=p --tablespace-mapping=/tmp/mytbsp=/tmp/mytbsp2backup -D plainbackup
6、流复制场景下使用表空间?
流复制场景下表空间的使用稍微复杂点,因为新表空间的路径没有同步到备用服务器上。备用服务器上会期望在与主服务器相同的位置上有一个现有目录,并在该位置上创建一个表空间。
7、使用表空间的优点?
当存储分区没有空间时,可以使用表空间把数据存到其他分区。
利用表空间对数据库进行性能优化。如频繁使用的数据表或索引放在高性能的硬盘上,而较少使用的放在普通硬盘上。(注意,这时候需要调整表空间参数:seq_page_cost和random_page_cost,见:https://www.postgresql.org/docs/10/runtime-config-query.html#GUC-SEQ-PAGE-COST,以便让查询优化器了解到这些信息。)
8、使用表空间的缺点?
使用表空间使数据库管理(比如备份和流复制)更加复杂,因为数据目录不再包含所有数据。
9、其他
临时表空间: 临时表和索引是由PostgreSQL在显式请求(“CREATE TEMP TABLE..”)或需要临时保存大数据集以完成查询时创建的。可以告诉PG将这些对象放在单独的表空间中。例如,如果在正常过程中创建了太多临时表,那么可以通过将这些对象放在具有更快、更大、未压缩文件系统甚至内存文件系统的表空间中来加快查询速度。使用选项temp_tablespaces告诉Postgres使用哪个表空间创建临时表。
另外:我看到有的文章中写到,并不推荐在pg中使用自定义表空间。见:https://www.cybertec-postgresql.com/en/when-to-use-tablespaces-in-postgresql/。因为我并没有在生产环境中使用过自定义表空间,所以对他谈到的利弊并没有深刻认知,大家酌情来看。
参考:
https://pgdash.io/blog/tablespaces-postgres.html
https://www.cybertec-postgresql.com/en/when-to-use-tablespaces-in-postgresql/
https://www.postgresql.org/docs/10/manage-ag-tablespaces.html




