Табличные пространства

Изначально в кластере присутствуют два табличных пространства. Информация о них содержится в системном каталоге:

=> SELECT spcname FROM pg_tablespace;
  spcname   
------------
 pg_default
 pg_global
(2 rows)

Конечно, это одна из глобальных для всего кластера таблиц.


Аналогичная команда psql:

=> \db
       List of tablespaces
    Name    |  Owner   | Location 
------------+----------+----------
 pg_default | postgres | 
 pg_global  | postgres | 
(2 rows)


Чтобы создать новое табличное пространство, надо подготовить пустой каталог, владельцем которого является пользователь, запускающий сервер СУБД:

postgres$ mkdir /var/lib/postgresql/ts_dir

Теперь выполняем команду, указывая каталог:

=> CREATE TABLESPACE ts LOCATION '/var/lib/postgresql/ts_dir';
CREATE TABLESPACE

=> \db
                List of tablespaces
    Name    |  Owner   |          Location          
------------+----------+----------------------------
 pg_default | postgres | 
 pg_global  | postgres | 
 ts         | student  | /var/lib/postgresql/ts_dir
(3 rows)


При создании базы данных можно указать табличное пространство по умолчанию:

=> CREATE DATABASE test TABLESPACE ts;
CREATE DATABASE
=> \c test
You are now connected to database "test" as user "student".

Это означает, что все объекты по умолчанию будут создаваться в этом табличном пространстве.

=> CREATE TABLE t(s text);
CREATE TABLE
=> INSERT INTO t SELECT g.id::text FROM generate_series(1,100000) g(id);
INSERT 0 100000
=> CREATE INDEX ON t(s);
CREATE INDEX
=> VACUUM t;
VACUUM

Узнать расположение файлов, относящихся к объекту, можно так:

=> SELECT pg_relation_filepath('t');
              pg_relation_filepath               
-------------------------------------------------
 pg_tblspc/103104/PG_9.6_201608131/103105/103106
(1 row)


Посмотрим на сами файлы:

postgres$ ls -l $PGDATA/pg_tblspc/103104/PG_9.6_201608131/103105/103106*
-rw------- 1 postgres postgres 3620864 сен  1 15:51 /var/lib/postgresql/9.6/main/pg_tblspc/103104/PG_9.6_201608131/103105/103106
-rw------- 1 postgres postgres   24576 сен  1 15:51 /var/lib/postgresql/9.6/main/pg_tblspc/103104/PG_9.6_201608131/103105/103106_fsm
-rw------- 1 postgres postgres    8192 сен  1 15:51 /var/lib/postgresql/9.6/main/pg_tblspc/103104/PG_9.6_201608131/103105/103106_vm

Видно, что они относятся к трем слоям: основному, vm и fsm.


Объекты можно перемещать между табличными пространствами, но (в отличие от схем) это приводит к физическому перемещению данных:

=> ALTER TABLE t SET TABLESPACE pg_default;
ALTER TABLE
=> SELECT pg_relation_filepath('t');
 pg_relation_filepath 
----------------------
 base/103105/103113
(1 row)


Размер объектов

Узнать размер, занимаемый базой данных и объектами в ней, можно с помощью ряда функций.

=> SELECT pg_database_size('test');
 pg_database_size 
------------------
         12915496
(1 row)

Для упрощения восприятия можно вывести число в отформатированном виде:

=> SELECT pg_size_pretty(pg_database_size('test'));
 pg_size_pretty 
----------------
 12 MB
(1 row)


Полный размер таблицы (вместе со всеми индексами):

=> SELECT pg_size_pretty(pg_total_relation_size('t'));
 pg_size_pretty 
----------------
 5776 kB
(1 row)


И отдельно размер таблицы...

=> SELECT pg_size_pretty(pg_table_size('t'));
 pg_size_pretty 
----------------
 3576 kB
(1 row)

...и индексов:

=> SELECT pg_size_pretty(pg_indexes_size('t'));
 pg_size_pretty 
----------------
 2200 kB
(1 row)


При желании можно узнать и размер отдельных слоев таблицы, например:

=> SELECT pg_size_pretty(pg_relation_size('t','vm'));
 pg_size_pretty 
----------------
 8192 bytes
(1 row)


Размер табличного пространства показывает другая функция:

=> SELECT pg_size_pretty(pg_tablespace_size('ts'));
 pg_size_pretty 
----------------
 9041 kB
(1 row)


Удалим базу данных.

=> \c postgres
You are now connected to database "postgres" as user "student".
=> DROP DATABASE test;
DROP DATABASE

После того, как в табличном пространстве не осталось объектов, можно удалить и его:

=> DROP TABLESPACE ts;
DROP TABLESPACE

Конец демонстрации.