1. Архитектура PostgreSQL: процессы, управление памятью и физическое хранение данных
Архитектура PostgreSQL: процессы, управление памятью и физическое хранение данных
Добро пожаловать в курс «PostgreSQL: От основ к продвинутой разработке и администрированию». Мы начинаем наше погружение не с написания простых запросов, а с фундамента — архитектуры. Понимание того, как база данных устроена «под капотом», отличает профессионального инженера данных от новичка. Это знание поможет вам в будущем оптимизировать сложные запросы, настраивать сервер и решать проблемы производительности.
PostgreSQL — это мощная объектно-реляционная система управления базами данных (ORDBMS). Она основана на классической клиент-серверной модели, но имеет свои уникальные особенности реализации, о которых мы поговорим в этой статье.
Процессная модель PostgreSQL
Первое, что нужно усвоить: PostgreSQL — это система, основанная на процессах, а не на потоках (threads). Это важное отличие от некоторых других СУБД (например, MySQL или MS SQL Server).
Когда вы запускаете PostgreSQL, на сервере операционной системы стартует несколько взаимодействующих процессов. Давайте разберем их иерархию.
!Общая схема взаимодействия процессов, памяти и диска в PostgreSQL
1. Postmaster (Main Process)
Это главный процесс, который запускается первым. Его задачи:
* Загрузка конфигурационных файлов (postgresql.conf, pg_hba.conf).
* Выделение общей памяти (Shared Memory).
* Прослушивание порта (по умолчанию 5432) в ожидании входящих подключений.
* Запуск фоновых процессов.
Когда клиент (ваше приложение или psql) пытается подключиться к базе данных, он обращается именно к Postmaster.
2. Backend процессы (Server Processes)
Как только Postmaster одобряет подключение клиента, он «порождает» (используя системный вызов fork) новый отдельный процесс — Backend process (часто называемый просто postgres).
> Один клиент = Один Backend процесс.
Этот процесс обслуживает только одного клиента и живет до тех пор, пока клиент не отключится. Он принимает SQL-запросы, компилирует их, выполняет и возвращает результат. Изоляция процессов обеспечивает стабильность: если один Backend процесс упадет из-за ошибки, это не обрушит весь сервер.
3. Фоновые процессы (Background Workers)
Это служебные процессы, которые выполняют задачи по обслуживанию базы данных. Пользователь не взаимодействует с ними напрямую. Вот ключевые из них:
* Background Writer: Периодически сбрасывает «грязные» (измененные) страницы данных из оперативной памяти на диск, чтобы освободить место для новых данных. * Checkpointer: Отвечает за создание контрольных точек (checkpoints). Это момент, когда гарантируется, что все данные из памяти физически записаны в файлы данных. * Autovacuum Launcher: Запускает процессы очистки (vacuum), которые удаляют старые версии строк и обновляют статистику для планировщика запросов. * WAL Writer: Записывает данные из буфера журнала предзаписи (Write-Ahead Log) на диск. Это критически важно для надежности данных.
Управление памятью
Память в PostgreSQL делится на две большие категории: общая память (Shared Memory) и локальная память (Local Memory).
Общая память (Shared Memory)
Эта область памяти выделяется при старте сервера и доступна всем процессам (Backend и фоновым). Она используется для кэширования данных и координации работы.
SELECT, PostgreSQL сначала ищет данные здесь. Если их нет, он читает их с диска и помещает в Shared Buffers.Локальная память (Local Memory)
Эта память выделяется индивидуально для каждого Backend процесса. Она используется для выполнения конкретных операций запроса.
* work_mem: Память для операций сортировки (ORDER BY), хеширования (HASH JOIN) и группировки. Если запросу нужно больше памяти, чем указано в work_mem, PostgreSQL начинает использовать временные файлы на диске, что резко снижает производительность.
* maintenance_work_mem: Память для операций обслуживания, таких как создание индексов (CREATE INDEX) или VACUUM.
* temp_buffers: Буфер для временных таблиц.
Для грубой оценки максимального потребления памяти можно использовать следующую формулу:
Где: * — максимальное потребление оперативной памяти. * — размер общих буферов (Shared Buffers). * — максимальное количество одновременных подключений (max_connections). * — размер памяти для рабочих операций (work_mem).
Важно понимать, что один сложный запрос может использовать work_mem несколько раз (для каждого узла сортировки или хеширования), поэтому реальное потребление может быть выше.
Физическое хранение данных
Теперь спустимся на уровень файловой системы. Все данные кластера PostgreSQL хранятся в директории, на которую указывает переменная окружения PGDATA (обычно /var/lib/postgresql/data).
Структура файлов
Внутри PGDATA вы найдете множество подпапок:
* base/: Здесь лежат базы данных по умолчанию. Каждая база данных — это подпапка с числовым идентификатором (OID).
* global/: Общие таблицы для всего кластера (например, список пользователей pg_authid).
* pg_wal/: Журналы предзаписи (Write-Ahead Logs). Это «черный ящик» базы данных, куда записываются все транзакции перед тем, как попасть в основные файлы.
Страницы и Кортежи (Pages and Tuples)
PostgreSQL хранит данные внутри файлов блоками фиксированного размера, которые называются страницами (pages). По умолчанию размер страницы составляет 8 КБ.
!Анатомия страницы данных в PostgreSQL
Внутри страницы находятся:
Почему «версии строк»? PostgreSQL использует модель MVCC (Multi-Version Concurrency Control). Когда вы обновляете строку (UPDATE), старая версия не удаляется и не перезаписывается. Вместо этого создается новая версия строки в той же или другой странице, а старая помечается как «мертвая». Это позволяет читающим транзакциям видеть старые данные, пока пишущая транзакция еще не завершилась, обеспечивая высокую конкурентность без блокировок чтения.
TOAST
Если вы попытаетесь сохранить в поле очень большой текст или JSON, который не помещается в одну страницу (8 КБ), PostgreSQL использует механизм TOAST (The Oversized-Attribute Storage Technique). Большие данные нарезаются на кусочки, сжимаются и сохраняются в отдельной системной таблице, а в основной таблице остается только ссылка на них.
Write-Ahead Logging (WAL)
Это один из самых важных концептов для обеспечения надежности. Идея проста: любое изменение сначала записывается в журнал (WAL), и только потом применяется к файлам данных.
Если сервер внезапно обесточится, данные в оперативной памяти (Shared Buffers) пропадут. Но при следующем запуске PostgreSQL прочитает WAL-файлы и «проиграет» все транзакции, которые были подтверждены, но не успели записаться в файлы данных. Это гарантирует целостность базы данных.
Резюме
В этой статье мы разобрали три кита архитектуры PostgreSQL:
postgres, а фоновые процессы обслуживают систему.work_mem используется локально для сложных запросов.В следующей части курса мы перейдем к установке PostgreSQL и настройке рабочего окружения, чтобы увидеть все эти компоненты в действии.