3.1 Кластер - это один каталог
Слово «кластер» здесь сбивает с толку: речь не про несколько машин. В PostgreSQL кластер - это один каталог с данными и один набор процессов, обслуживающий сразу несколько баз. Каталог называют PGDATA - по имени переменной окружения, которая на него указывает.
SHOW data_directory;
-- /var/lib/postgresql/data
Одна установка сервера - один кластер - один PGDATA - много баз внутри. Когда говорят «поднял Postgres», обычно имеют в виду именно это: один кластер. Подробный разбор каталога - в cluster-pgdata.
3.2 Что внутри PGDATA
Раскладка каталога одинакова на любой установке. Главные обитатели:
| Каталог | Что хранит |
|---|---|
base/ | данные всех обычных баз, по подкаталогу на базу |
global/ | объекты, общие для кластера (список баз, роли) |
pg_wal/ | журнал предзаписи (WAL) |
pg_xact/ | статусы транзакций (clog) |
postgresql.conf | конфигурация сервера |
Каждая база внутри base/ - это подкаталог, названный по числовому
идентификатору базы (OID). То есть «база» физически - это папка с
файлами таблиц и индексов. Размер базы на диске - это размер её папки.
3.3 Базы и шаблоны
Свежий кластер уже содержит три базы:
SELECT oid, datname FROM pg_database ORDER BY oid;
-- oid | datname
-- -------+-----------
-- 1 | template1
-- 4 | template0
-- 5 | postgres
-- 16384 | lab <- наша учебная база
template1 и template0 - шаблоны. Когда ты делаешь CREATE DATABASE,
PostgreSQL физически копирует template1. Поэтому всё, что положишь в
template1, попадёт в каждую новую базу. template0 держат
нетронутым - как чистый эталон на случай, если template1 испортили.
База postgres - просто удобная база по умолчанию.
Базы изолированы: подключившись к одной, ты не видишь таблицы другой. Чтобы работать с другой базой, нужно отдельное соединение к ней.
3.4 Схемы: папки внутри базы
Внутри базы объекты разложены по схемам - это пространства имён.
Две таблицы с именем orders спокойно живут в разных схемах и не
конфликтуют. По умолчанию объекты создаются в схеме public.
SELECT current_schema(); -- public
SHOW search_path; -- "$user", public
search_path - это список схем, в которых сервер ищет объект по
неполному имени. Пишешь SELECT * FROM flights - сервер идёт по
search_path и берёт первую найденную flights. Полное имя
public.flights обходит поиск и указывает схему явно.
Схемы - это логическая организация, не физическая: на диске они не
создают отдельных каталогов. Все таблицы базы лежат в одном подкаталоге
base/<oid>/, а к какой схеме они относятся, записано в системном
каталоге.
3.5 Табличные пространства: данные на другом диске
По умолчанию всё лежит внутри PGDATA. Но таблицу, индекс или целую базу можно положить на другой диск через табличное пространство (tablespace) - именованную ссылку на каталог вне PGDATA.
SELECT spcname FROM pg_tablespace;
-- pg_default <- обычные данные (внутри PGDATA)
-- pg_global <- общие объекты кластера
Два пространства есть всегда: pg_default (данные по умолчанию) и
pg_global (общесистемные объекты). Свои создают, чтобы развести
нагрузку по дискам: горячие индексы - на быстрый SSD, архивные
таблицы - на медленный и дешёвый. Внутри base/ тогда останется лишь
символическая ссылка. Это инструмент уровня администрирования, и в
обычной работе его не трогают.
3.6 Путь от базы до таблицы
Сложим иерархию в одну строчку пути. Данные таблицы лежат по адресу
base/<oid базы>/<имя файла таблицы>. Первое число - OID базы,
второе - идентификатор файла отношения.
SELECT pg_relation_filepath('flights');-- base/16384/16503
16384 - это OID нашей базы lab (совпадает со строкой из
pg_database). 16503 - имя файла таблицы flights. Откуда берётся
второе число, чем оно отличается от OID и почему у таблицы не один
файл, а несколько - разбирает следующая глава.
Уроки в sandbox
lab-3.1. Экскурсия по кластеру
Пройди иерархию хранения сверху вниз: кластер, базы, схемы, табличные
пространства. Перед каждым запросом предскажи результат - сколько баз
в кластере, в какой схеме лежит flights, какой OID у базы lab.
Узнай каталог данных кластера:
SHOW data_directory;.Предскажи, сколько баз в кластере, и проверь:
SELECT count(*) FROM pg_database;(учти три системные базы плюс учебную).Посмотри список баз с OID:
SELECT oid, datname FROM pg_database ORDER BY oid;- найди базуlabи запомни её OID.Узнай текущую схему и путь поиска:
SELECT current_schema();иSHOW search_path;.Посмотри табличные пространства:
SELECT spcname FROM pg_tablespace;- предскажи, сколько их на свежем кластере.Сложи путь до таблицы:
SELECT pg_relation_filepath('flights');и убедись, что число базы в пути совпадает с OID базыlab.
sandbox с автопроверкой - открыть в песочнице
Резюме
- Кластер - это один каталог PGDATA и один набор процессов, обслуживающий несколько баз.
- Внутри PGDATA: base/ (данные баз по OID), global/ (общее), pg_wal/ (журнал), pg_xact/ (статусы транзакций).
- Новые базы создаются копированием template1; template0 - чистый эталон, postgres - база по умолчанию.
- Схемы - это пространства имён внутри базы; search_path задаёт, где искать объект по короткому имени.
- Табличные пространства выносят данные на другой диск через ссылку вне PGDATA.
- Путь к таблице - base/<oid базы>/<имя файла>; первое число совпадает с OID базы из pg_database.
Контрольные вопросы
Почему «кластер» в PostgreSQL не означает несколько серверов?
Показать ответ
Потому что кластер здесь - это один каталог данных (PGDATA) и один набор процессов на одной машине, обслуживающий несколько баз. Слово описывает «кластер баз под одним сервером», а не группу машин. Несколько физических серверов - это уже репликация или шардирование, отдельная тема.
Что произойдёт с новой базой, если положить таблицу в template1?
Показать ответ
Она появится в каждой новой базе.
CREATE DATABASEфизически копируетtemplate1, поэтому всё его содержимое наследуется новыми базами. Это используют, чтобы преднастроить расширения или служебные объекты во всех будущих базах.template0для этого трогать нельзя - он держится как чистый эталон.Чем схема отличается от базы и где схемы лежат физически?
Показать ответ
База - это единица изоляции: подключившись к одной базе, не видишь объекты другой, нужно отдельное соединение. Схема - пространство имён внутри одной базы: разные схемы могут содержать одноимённые таблицы. Физически отдельных каталогов схемы не создают - все таблицы базы лежат в одном подкаталоге
base/<oid>/, а принадлежность к схеме записана в системном каталоге.Что делает search_path и зачем иногда писать полное имя схемы?
Показать ответ
search_path- список схем, в которых сервер ищет объект, названный коротко. Сервер берёт первую найденную таблицу с этим именем. Полное имя (public.flights) обходит поиск и однозначно указывает схему - это важно, когда одноимённые объекты есть в нескольких схемах или когда нужна предсказуемость независимо от текущегоsearch_path.Зачем нужны табличные пространства?
Показать ответ
Чтобы вынести данные за пределы PGDATA, обычно на другой диск. Табличное пространство - именованная ссылка на внешний каталог. Так разводят нагрузку: горячие индексы кладут на быстрый диск, архивные таблицы - на медленный и ёмкий. Это инструмент администрирования; в обычной разработке хватает пространства по умолчанию
pg_default.