PostgreSQL
Установка и конфигурация
Цели урока
- Установить PostgreSQL на Ubuntu, macOS или RHEL, понять что делает initdb
- Настраивать postgresql.conf через SHOW/SET/ALTER SYSTEM
- Конфигурировать pg_hba.conf для безопасного доступа
- Настроить пять ключевых параметров производительности для конкретного железа
- Запустить production-ready PostgreSQL в Docker с volume и healthcheck
Предварительные знания
Разработчик устанавливает PostgreSQL, запускает приложение - всё работает. Через месяц трафик вырастает - запросы тормозят, подключения таймаутятся, disk I/O на 100%. Проблема не в PostgreSQL. Проблема в том, что shared_buffers = 128MB на сервере с 32GB RAM - это как мотор газонокосилки в Ferrari.
- **Стартап на Heroku** - трафик вырос в 10 раз за ночь, нужно перенастроить параметры памяти без даунтайма за минуты
- **DevOps** разворачивает PostgreSQL в Kubernetes - docker-compose, volumes, health checks, кастомная конфигурация
- **Разработчик** получает `FATAL: no pg_hba.conf entry` при подключении с нового IP - pg_hba.conf единственный путь вперёд
- **Команда** переезжает на новый сервер - забыли перенести pg_hba.conf, теперь никто не может подключиться
- **Production incident** - work_mem = 512MB при 200 параллельных сложных запросах съел всю RAM и сервер упал
Michael Stonebraker и проект POSTGRES
Stonebraker запустил POSTGRES в Беркли в 1986 году как преемник Ingres. Главная идея: поддержка пользовательских типов данных и правил - расширяемость, которой не было в других СУБД. В 1996 году проект стал open-source и получил SQL, сменив название на PostgreSQL. Stonebraker получил премию Тьюринга в 2014 году. Сегодня PostgreSQL - единственная БД в топ-5, не принадлежащая корпорации.
Установка PostgreSQL
Первый запуск PostgreSQL занимает 5 минут. Неправильная установка будет стоить часов отладки. Разберём, как установить PostgreSQL на любой ОС, что делает initdb и как управлять несколькими версиями одновременно.
**initdb** - команда, которая создаёт кластер базы данных: структуру директорий, системные каталоги, конфигурационные файлы. На Ubuntu/Debian initdb вызывается автоматически при установке. На RHEL/Fedora - нужно запустить вручную.
**На Ubuntu можно держать несколько кластеров** одновременно. Утилита pg_lsclusters показывает все установленные кластеры:
**pgenv** - менеджер версий PostgreSQL (аналог nvm для Node.js). Удобен для разработки когда нужно тестировать на разных версиях: `pgenv install 17.2 && pgenv use 17.2`
Что делает команда initdb?
postgresql.conf - главный конфиг
**postgresql.conf - центр управления PostgreSQL.** Здесь сотни параметров: от адреса, на котором слушает сервер, до размера буферов и поведения планировщика запросов. Файл расположен в директории кластера (`/var/lib/postgresql/17/main/postgresql.conf` на Ubuntu).
**Три способа изменить параметры** - и каждый имеет свою область применения:
**ALTER SYSTEM записывает в postgresql.auto.conf**, а не в postgresql.conf. Параметры из auto.conf имеют приоритет. Если postgresql.conf правится вручную, а значение не применяется - проверить, нет ли перекрытия в auto.conf.
**listen_addresses = 'localhost'** по умолчанию означает, что PostgreSQL принимает подключения только с той же машины. Для доступа извне изменить на `'*'` или конкретный IP - но обязательно настроить pg_hba.conf для безопасности.
Выполнено ALTER SYSTEM SET work_mem = '64MB'. Когда изменение вступит в силу?
pg_hba.conf - кто может подключиться
**pg_hba.conf (Host-Based Authentication)** - файрвол PostgreSQL. Определяет, кто, откуда и каким способом может подключаться к серверу. Даже при правильном пароле - без соответствующего правила в pg_hba.conf подключение будет отклонено. Именно поэтому ошибка `FATAL: no pg_hba.conf entry for host` - одна из самых частых при первом деплое.
| Метод | Описание | Когда использовать |
|---|---|---|
| trust | Без пароля - доверяем полностью | Только для локальной разработки. НИКОГДА в production |
| peer | Пользователь ОС = пользователь PostgreSQL | Локальные Unix-сокеты (sudo -u postgres psql) |
| md5 | Хешированный пароль (устаревший) | Legacy-совместимость |
| scram-sha-256 | Современная аутентификация (с v10) | Production - стандарт де-факто |
| cert | SSL-сертификат клиента | Максимальная безопасность, без паролей |
| reject | Отклонить подключение | Явный запрет для определённых пользователей/IP |
**Порядок правил критически важен!** PostgreSQL проверяет строки сверху вниз и применяет ПЕРВОЕ подходящее правило. Если `reject` стоит после `trust` для того же диапазона - reject никогда не сработает.
**Типичная ошибка при первом деплое:** `FATAL: no pg_hba.conf entry for host "192.168.1.5"`. IP-адрес клиента не соответствует ни одному правилу в pg_hba.conf. Добавить правило для этого IP или подсети.
В pg_hba.conf стоит: `host all all 0.0.0.0/0 trust`. Что это означает?
Ключевые параметры настройки
Из 300+ параметров PostgreSQL, 90% производительности определяются пятью. PostgreSQL намеренно поставляется с консервативными defaults - они рассчитаны на машину с 512MB RAM. На сервере с 32GB это значит, что shared_buffers = 128MB использует менее 1% доступной памяти. Результат: сервер постоянно читает с диска вместо кеша.
| Параметр | По умолчанию | Рекомендация | Что делает |
|---|---|---|---|
| shared_buffers | 128 MB | 25% RAM | Размер главного буферного кеша. Все данные проходят через него |
| effective_cache_size | 4 GB | 50-75% RAM | Подсказка планировщику о доступном кеше ОС. Не выделяет память! |
| work_mem | 4 MB | 32-256 MB | Память на одну операцию сортировки/хеша. Осторожно: умножается на число операций и сессий |
| maintenance_work_mem | 64 MB | 512 MB - 2 GB | Память для VACUUM, CREATE INDEX, ALTER TABLE |
| max_connections | 100 | 50-200 | Макс. одновременных подключений. Каждое использует ~5-10MB RAM |
**work_mem - самый обманчивый параметр.** Один сложный запрос может использовать work_mem несколько раз - по одному разу на каждую операцию сортировки или хеша. При work_mem = 256MB и запросе с четырьмя операциями сортировки - 1GB RAM для одного запроса. Умножить на 50 параллельных запросов - 50GB.
**effective_cache_size не выделяет память!** Это подсказка планировщику запросов: «при выборе между Index Scan и Sequential Scan считай, что ~12GB данных уже могут быть закешированы ОС». Увеличение этого значения заставляет планировщик чаще использовать индексы.
**pgtune** (https://pgtune.leopard.in.ua/) - онлайн-калькулятор настройки PostgreSQL. Ввести характеристики сервера и тип нагрузки (OLTP/OLAP/Mixed) - получить оптимизированные значения всех ключевых параметров.
Сервер с 32GB RAM, SSD, OLTP-нагрузка. Какое значение shared_buffers оптимально?
PostgreSQL в Docker
**Docker - самый быстрый способ запустить PostgreSQL для разработки.** Одна команда, рабочий сервер через 10 секунд. Но есть несколько ловушек, которые убивают данные, если о них не знать заранее.
**Без volume все данные исчезнут!** Контейнер хранит данные внутри себя. `docker rm pg-dev` уничтожит каждую базу, каждую таблицу, каждую строку. Всегда монтировать volume для `/var/lib/postgresql/data`.
**shm_size** - важный параметр Docker. По умолчанию Docker выделяет только 64MB shared memory, но PostgreSQL может требовать больше - особенно при увеличенном shared_buffers. Ошибка `could not resize shared memory segment` - сигнал увеличить shm_size.
**Для Mac M1/M2:** при сборке Docker-образа для деплоя на x86_64 сервер всегда указывать платформу: `docker build --platform linux/amd64`. Без этого флага получится `exec format error` на сервере.
Настройки PostgreSQL по умолчанию достаточны для production - просто установить и запустить
Defaults рассчитаны на минимальные ресурсы: shared_buffers=128MB, work_mem=4MB, max_connections=100. Production требует тюнинга под реальное железо сервера.
PostgreSQL намеренно поставляется с консервативными defaults - чтобы запуститься даже на машине с 512MB RAM. На сервере с 32GB defaults используют менее 1% доступной производительности. Без тюнинга shared_buffers настолько мал, что PostgreSQL будет постоянно читать с диска, а маленький work_mem будет сбрасывать операции сортировки на диск.
PostgreSQL запущен командой `docker run` без флага `-v`. Что произойдёт при `docker rm`?
Ключевые идеи
- **Установка:** apt/brew + initdb создаёт кластер. pg_lsclusters управляет несколькими версиями на Ubuntu
- **postgresql.conf** - центр управления. SHOW/SET для инспекции, ALTER SYSTEM для постоянных изменений, pg_reload_conf() для применения без рестарта
- **pg_hba.conf** - файрвол PostgreSQL. Порядок правил важен: первое совпавшее правило применяется. scram-sha-256 в production, trust только локально
- **Пять ключевых параметров:** shared_buffers (25% RAM), effective_cache_size (75% RAM), work_mem (с осторожностью), maintenance_work_mem, max_connections
- **Docker:** всегда монтировать volume, использовать healthcheck, передавать параметры через command, shm_size >= 128MB
- shared_buffers = 128MB на 32GB RAM - это 0.4% использования мощности сервера
Связанные темы
Конфигурация PostgreSQL - отправная точка для тюнинга и безопасности:
- Типы данных — Следующий шаг: какие типы данных предоставляет PostgreSQL
- Тюнинг памяти — Глубокий разбор shared_buffers, work_mem и других параметров памяти
- Безопасность — Расширенная конфигурация pg_hba.conf, SSL, Row-Level Security
Вопросы для размышления
- При 100 микросервисах с пулом из 10 соединений каждый - хватит ли max_connections = 100? Что изменить?
- Почему рекомендованный shared_buffers - 25% RAM, а не 75%? Куда уходит остальная память?
- При переезде на новый сервер забыли перенести pg_hba.conf. Какая ошибка появится и как её исправить?
Связанные уроки
- pg-01-intro — Архитектура PostgreSQL - контекст для понимания конфига
- pg-03-data-types — Следующий шаг: типы данных PostgreSQL
- pg-43-tuning-memory — Глубокий dive в shared_buffers, work_mem, buffer cache
- pg-48-security — Расширенная настройка pg_hba.conf, SSL, Row-Level Security
- pg-45-tuning-connections — max_connections, PgBouncer - connection pooling в production
- db-01-intro — Базовое понимание зачем вообще нужна СУБД
- db-03-acid