PostgreSQL

Установка и конфигурация

Цели урока

  • Установить PostgreSQL на Ubuntu, macOS или RHEL, понять что делает initdb
  • Настраивать postgresql.conf через SHOW/SET/ALTER SYSTEM
  • Конфигурировать pg_hba.conf для безопасного доступа
  • Настроить пять ключевых параметров производительности для конкретного железа
  • Запустить production-ready PostgreSQL в Docker с volume и healthcheck

Предварительные знания

  • PostgreSQL: история и архитектура

Разработчик устанавливает 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 - стандарт де-факто
certSSL-сертификат клиентаМаксимальная безопасность, без паролей
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_buffers128 MB25% RAMРазмер главного буферного кеша. Все данные проходят через него
effective_cache_size4 GB50-75% RAMПодсказка планировщику о доступном кеше ОС. Не выделяет память!
work_mem4 MB32-256 MBПамять на одну операцию сортировки/хеша. Осторожно: умножается на число операций и сессий
maintenance_work_mem64 MB512 MB - 2 GBПамять для VACUUM, CREATE INDEX, ALTER TABLE
max_connections10050-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
Установка и конфигурация

0

1

Войти