postgres tablespace - ghdrako/doc_snipets GitHub Wiki

By default, PostgreSQL stores its data in a directory that is defined in the environmental variable called PGDATA. Tables and other objects are created within this directory in a separate file. You can create tablespaces outside of the default PGDATA data directory for larger systems, to isolate data from indexes, to create storage for application-related subject areas, to improve performance by creating tables on SSD devices, and to specify separate storage for partitions.

A tablespace is a directory that can be outside the PGDATA directory and can also belong to different storage. Tablespaces are mapped into the PGDATA directory by means of symbolic links stored in the pg_tblspc subdirectory. In this way, the PostgreSQL processes do not have to look outside PGDATA, but are still able to access “external” storage. A tablespace can be used to achieve different aims, such as enlarging the storage data or providing different stor- age performances for specific objects. For instance, you can create a tablespace on a slow disk to contain infrequently accessed objects and tables, keeping fast storage within another tablespace for frequently accessed objects.

Create tablespace

When you create tablespace(s), the database files are created outside the default data directory; however, there is a symbolic link from the data directory to the location of the tablespace data file location. During the backup, PostgreSQL backs up all the data from the tablespaces. There are two default tablespaces: the default for user data and the system catalog data. There is a symbolic link from the pg_tblspc to the filesystem.

obraz

Create a directory as shown:

$ sudo mkdir -p /newtablespace
$ sudo chown postgres:postgres /newtablespace

Now create a tablespace using the newly created directory by running the following command:

$ psql -c "CREATE TABLESPACE newtblspc LOCATION '/newtablespace'"

Check the pg_tblspc directory to see a symlink to the new tablespace:

$ ls -l $PGDATA/pg_tblspc
 total 0
 lrwxrwxrwx. 1 postgres postgres 14 Nov 3 00:24 24611 -> /newtablespace

List tablespaces

postgres=# \db
 List of tablespaces
 Name | Owner | Location
 ------------+----------+----------------
 newtblspc | postgres | /newtablespace
 pg_default | postgres |
 pg_global | postgres |

Create tables in specific tablespace

postgres=# create table employee (id int) TABLESPACE newtblspc;

If you create a table inside the new tablespace, here is how the relation path appears. In the following log, it shows how the table is pointing to the appropriate tablespace:

postgres=# select pg_relation_filepath('employee');
 pg_relation_filepath
 ---------------------------------------------
 pg_tblspc/24611/PG_13_201909212/14187/24612
 (1 row)

And now, if you describe the table, you should be able to see the tablespace in which the table got created:

postgres=# \d employee
 Table "public.employee"
 Column | Type | Collation | Nullable | Default
 --------+---------+-----------+----------+---------
 id | integer | | |
 Tablespace: "newtblspc"

Create tables in specific tablespace with the set Command

SET default_tablespace =data01;
DROP TABLE IF EXISTS log2023_m1;
CREATE TABLE log2023_m1 PARTITION OF log FOR VALUES FROM ('2023-01-01') TO ('2023-02-01');
SET default_tablespace =data02;
CREATE TABLE log2023_m2 PARTITION OF log FOR VALUES FROM ('2023-02-01') TO ('2023-03-01');

Move to tablespace

To move a table to another tablespace, the syntax looks like the following:

ALTER TABLE <schemaname.tablename> SET TABLESPACE <tablespace_name>;
ALTER TABLE percona.foo SET TABLESPACE newtblspc;

To move an index to a new tablespace, the syntax looks like the following:

ALTER TABLE <schemaname.indexname> SET TABLESPACE <tablespace_name>;
ALTER INDEX percona.foo_id_idx SET TABLESPACE newtblspc;

Find location of Tables in a Tablespace

SELECT pg_relation_filepath('log2023_m1');
            pg_relation_filepath
---------------------------------------------
 pg_tblspc/16384/PG_14_202107181/13748/16399
(1 row)
postgres=# SELECT pg_relation_filepath('log');
 pg_relation_filepath
----------------------
postgres=# SELECT pg_relation_filepath('log_default');
 base/13748/1640