Физическая структура кластера баз данных PostgreSQL
Кластер базы данных по сути представляет собой один каталог, называемый базовым каталогом. Он содержит несколько подкаталогов и множество файлов. Когда вы запускаете утилиту initdb для инициализации нового кластера базы данных, в указанном каталоге будет создан базовый каталог. Путь к базовому каталогу обычно указывается в переменной среды PGDATA.
На рисунке 2 показан пример кластера баз данных в PostgreSQL. База данных - это подкаталог в базовом подкаталоге, а каждая из таблиц и индексов - это (как минимум) один файл, хранящийся в подкаталоге базы данных, к которой она принадлежит. Существует несколько подкаталогов, содержащих определенные файлы данных и конфигурации.
В следующих подпунктах описана схема кластера баз данных, самих баз данных, файлов, связанных с таблицами и индексами, а также табличных пространств.
Расположение кластера баз данных
Расположение кластера баз данных описано в официальном документе. Основные файлы и подкаталоги перечислены в таблице 1.1:
Таблица 1.1: Расположение файлов и подкаталогов в базовом каталоге (выдержка из официального документа)
|
Файлы |
Описание |
|
PG_VERSION |
Файл, содержащий номер основной версии PostgreSQL |
|
pg_hba.conf |
Файл, управляющий аутентификацией клиента |
|
pg_ident.conf |
Файл, управляющий сопоставлением имен пользователей PostgreSQL. |
|
postgresql.conf |
Файл, используемый для установки параметров конфигурации. |
|
postgresql.auto.conf |
Файл, используемый для хранения параметров конфигурации, которые устанавливаются при помощи ALTER SYSTEM |
|
postmaster.opts |
Файл, содержащий параметры командной строки, с которыми сервер был запущен в последний раз |
|
Подкаталоги |
Описание |
|
base/ |
Подкаталог, содержащий подкаталоги для каждой базы данных |
|
global/ |
Подкаталог, содержащий общие таблицы кластера, такие как pg_database |
|
pg_commit_ts/ |
Подкаталог, содержащий данные о времени фиксации транзакций |
|
pg_clog/ (versions 9.6 or earlier) |
Подкаталог, содержащий данные о состоянии транзакции. В версии 1- он переименован в pg_xact . Подробное описание CLOG см. в Разделе 5.4. |
|
pg_dynshmem/ |
Подкаталог, содержащий файлы, используемые подсистемой динамически разделяемой памяти |
|
pg_logical/ |
Подкаталог, содержащий данные о состоянии для логического декодирования |
|
pg_multixact/ |
Подкаталог, содержащий данные о состоянии мультитранзакций (используемые для разделяемой блокировки строк) |
|
pg_notify/ |
Подкаталог, содержащий данные состояния прослушивания и уведомлений (LISTEN/NOTIFY) |
|
pg_repslot/ |
Подкаталог, содержащий данные слота репликации |
|
pg_serial/ |
Подкаталог, содержащий информацию о выполненных сериализуемых транзакциях. |
|
pg_snapshots/ |
Подкаталог, содержащий экспортированные снимки (snapshots) |
|
pg_stat/ |
Подкаталог, содержащий постоянные файлы для подсистемы статистики. |
|
pg_stat_tmp/ |
Подкаталог, содержащий временные файлы для подсистемы статистики |
|
pg_subtrans/ |
Подкаталог, содержащий данные о состоянии подтранзакций |
|
pg_tblspc/ |
Подкаталог, содержащий символические ссылки на табличные пространства |
|
pg_twophase/ |
Подкаталог, содержащий файлы состояний для подготовленных транзакций |
|
pg_xlog/ (versions 9.6 or earlier) |
Подкаталог, содержащий файлы WAL (журнал предзаписи) |
Расположение баз данных
Имена подкаталогов соответствуют OID'ам баз данных. Например, если OID базы данных 'sampledb' равен 16384, имя ее подкаталога будет 16384.
$ cd $PGDATA $ ls -ld base/16384 drwx------ 213 postgres postgres 7242 8 26 16:33 16384
Расположение файлов, связанных с таблицами и индексами
Каждая таблица или индекс размером менее 1 ГБ хранится в одном файле в каталоге базы данных, к которому она принадлежит. Таблицы и индексы управляются индивидуальными OID, в то время как их файлы данных управляются переменной relfilenode. Значения relfilenode в основном (но не всегда) совпадают с соответствующими OID, подробности описаны ниже.
Рассмотрим OID и relfilenode таблицы 'sampletbl':
sampledb=# SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'sampletbl'; relname | oid | relfilenode -----------+-------+------------- sampletbl | 18740 | 18740 (1 row)
Таким образом, значения oid и relfilenode в данном случае полностью идентичны, путь к файлу данных таблицы 'sampletbl' следующий: 'base/16384/18740'.
$ cd $PGDATA $ ls -la base/16384/18740 -rw------- 1 postgres postgres 8192 Apr 21 10:21 base/16384/18740
Значение relfilenode можно изменить, выполнив определенные команды, такие как TRUNCATE, REINDEX, CLUSTER. Например, если мы выполним команду TRUNCATE для таблицы 'sampletbl', PostgreSQL сразу же присвоит ей новый relfilenode (18812), удалит старый файл данных (18740) и создаст новый (18812).
sampledb=# TRUNCATE sampletbl; TRUNCATE TABLE sampledb=# SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'sampletbl'; relname | oid | relfilenode -----------+-------+------------- sampletbl | 18740 | 18812 (1 row)
Примечание:
В версиях 9.0 и новее появилась встроенная функция pg_relation_filepath, которая возвращает полный путь к файлу (относительно каталога данных PGDATA ) отношения.
sampledb=# SELECT pg_relation_filepath('sampletbl');
pg_relation_filepath
----------------------
base/16384/18812
(1 row)
Когда размер файлов с таблицами и индексами превышает 1 ГБ, PostgreSQL создает новый файл с именем relfilenode.1 и использует его. Если новый файл будет полностью заполнен, PostgreSQL создаст еще один файл с именем relfilenode.2 и так далее.
$ cd $PGDATA $ ls -la -h base/16384/19427* -rw------- 1 postgres postgres 1.0G Apr 21 11:16 data/base/16384/19427 -rw------- 1 postgres postgres 45M Apr 21 11:20 data/base/16384/19427.1
Примечание:
Размер сегмента можно изменить при сборке PostgreSQL, используя параметр конфигурации with-segsize.
Если Вы посмотрите на подкаталоги базы данных внимательнее, то обнаружите, что каждая таблица имеет два связанных с ней файла с суффиксами '_fsm' и '_vm'. Это карта свободного пространства и карта видимости соответственно.
Карта свободного пространства хранит информацию о количестве свободного места на каждой странице в файле таблицы, а карта видимости - информацию о видимости каждой страницы в файле таблицы. (Более подробную информацию можно найти в разделах 5.3.4 и 6.2).
Пример показан ниже:
$ cd $PGDATA $ ls -la base/16384/18751* -rw------- 1 postgres postgres 8192 Apr 21 10:21 base/16384/18751 -rw------- 1 postgres postgres 24576 Apr 21 10:18 base/16384/18751_fsm -rw------- 1 postgres postgres 8192 Apr 21 10:18 base/16384/18751_vm
Табличное пространство
Табличные пространства позволяют задать место хранения объектов БД в файловой системе. Сначала создается табличное пространство с определенным именем. Далее, это имя может быть использовано при создании таблиц, чтобы разместить эти таблицы именно в данном табличном пространстве.
Для создания табличного пространства используется команда CREATE TABLESPACE, например:
CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
Если Вы создадите табличное пространство 'new_tblspc' по адресу '/home/postgres/tblspc' с OID 16386, под этим пространством будет создан подкаталог с именем 'PG_14_202011044.
$ ls -l /home/postgres/tblspc/ total 4 drwx------ 2 postgres postgres 4096 Apr 21 10:08 PG_14_202011044
К каталогу tablespace ведет ссылка из подкаталога pg_tblspc. Имя ссылки совпадает со значением OID каталога tablespace.
$ ls -l $PGDATA/pg_tblspc/ total 0 lrwxrwxrwx 1 postgres postgres 21 Apr 21 10:08 16386 -> /home/postgres/tblspc
Если Вы создаете новую таблицу, принадлежащую базе данных, имейте в виду, что сначала создается новый каталог в подкаталоге. Имя нового каталога совпадает с OID существующей базы данных. Затем в созданный каталог помещается файл новой таблицы.
sampledb=# CREATE TABLE newtbl (.....) TABLESPACE new_tblspc;
sampledb=# SELECT pg_relation_filepath('newtbl');
pg_relation_filepath
---------------------------------------------
pg_tblspc/16386/PG_14_202011044/16384/18894





