# Кейс: PostgreSQL (репликация и базовые запросы) Связь с легендой: [../../legend/LEGEND.md](../../legend/LEGEND.md) — раздел «Домашняя лаборатория / pet-проект». SQL как язык запросов уже вписан в легенду как сквозной инструмент (работа с данными сопровождаемых сервисов в АО ТНИИС), но отдельного опыта администрирования/репликации самой СУБД в рабочей практике не было — это тоже честный pet-кейс поверх рабочего опыта с запросами. ## Что нужно реально сделать (домашний стенд) Поднять master + одну streaming-реплику PostgreSQL в Docker Compose, попробовать синхронный и асинхронный режим репликации, прогнать `pgbench` для базовых цифр производительности и потренировать SQL-запросы на простой учебной схеме. ### 1. docker-compose.yml — master + replica ```yaml version: "3.8" services: pg-master: image: postgres:16 container_name: pg-master environment: POSTGRES_PASSWORD: labpass POSTGRES_USER: labuser POSTGRES_DB: labdb command: > postgres -c wal_level=replica -c max_wal_senders=5 -c max_replication_slots=5 -c synchronous_commit=on -c synchronous_standby_names='FIRST 1 (replica1)' volumes: - ./master-init.sql:/docker-entrypoint-initdb.d/init.sql ports: - "5432:5432" pg-replica: image: postgres:16 container_name: pg-replica environment: POSTGRES_PASSWORD: labpass PGUSER: labuser depends_on: - pg-master ports: - "5433:5432" entrypoint: > bash -c " until pg_basebackup -h pg-master -D /var/lib/postgresql/data -U labuser -Fp -Xs -P -R --slot=replica1 --create-slot; do echo waiting for master; sleep 2; done; echo \"primary_conninfo = 'host=pg-master port=5432 user=labuser application_name=replica1'\" >> /var/lib/postgresql/data/postgresql.auto.conf; exec postgres" ``` ### 2. master-init.sql — учебная схема ```sql CREATE TABLE customers ( id SERIAL PRIMARY KEY, name TEXT NOT NULL ); CREATE TABLE orders ( id SERIAL PRIMARY KEY, customer_id INT REFERENCES customers(id), amount NUMERIC(10,2), status TEXT ); INSERT INTO customers (name) VALUES ('Иванов'), ('Петров'), ('Сидоров'); INSERT INTO orders (customer_id, amount, status) VALUES (1, 1500.00, 'paid'), (1, 300.00, 'pending'), (2, 4200.00, 'paid'); ``` ### 3. Шаги воспроизведения 1. `docker compose up -d` — поднять master, дождаться, пока replica пройдёт `pg_basebackup` и подключится (`docker compose logs -f pg-replica`). 2. Проверить репликацию: `psql -h localhost -p 5432 -U labuser labdb -c "INSERT INTO customers (name) VALUES ('Новый клиент')"`, затем `psql -h localhost -p 5433 -U labuser labdb -c "SELECT * FROM customers"` — строка должна появиться на реплике. 3. Проверить статус на master: `SELECT * FROM pg_stat_replication;` — увидеть `replica1`, `state = streaming`, `sync_state = sync` (при заданном `synchronous_standby_names`). 4. Переключить на асинхронный режим: убрать `synchronous_standby_names` из command, перезапустить master, повторить `pg_stat_replication` — `sync_state` сменится на `async`. Разница на практике: при `sync` транзакция на master не считается закоммиченной, пока реплика не подтвердила запись (гарантия нуля потерянных данных при падении master ценой задержки commit); при `async` master коммитит сразу, не дожидаясь реплики (быстрее, но при падении master возможна потеря последних транзакций). 5. Погонять `pgbench` для базовых цифр: `pgbench -h localhost -p 5432 -U labuser -i labdb` (инициализация), `pgbench -h localhost -p 5432 -U labuser -c 10 -j 2 -T 30 labdb` (10 клиентов, 30 секунд) — записать TPS в [../../legend/CAPACITY.md](../../legend/CAPACITY.md). 6. Потренировать запросы на схеме `customers`/`orders`: JOIN, агрегации, `WHERE id = N` — см. [QUESTIONS.md](QUESTIONS.md). ## Что это даёт в разговоре с интервьюером - Практическое понимание разницы sync/async репликации не как определения, а как наблюдаемого поведения (`pg_stat_replication`, разная задержка commit). - Понимание streaming-репликации через WAL и `pg_basebackup` — как реплика вообще получает данные. - Базовые цифры TPS со своей лабы — честная отправная точка для разговора про производительность (см. [../../legend/CAPACITY.md](../../legend/CAPACITY.md)). - Уверенное владение основными типами JOIN и агрегатными запросами на конкретной схеме. ## Как это ложится в легенду PostgreSQL как СУБД — pet-кейс, не приписанный к опыту в компаниях. SQL как язык запросов к данным сопровождаемых сервисов остаётся в легенде как рабочий навык (см. [../../legend/LEGEND.md](../../legend/LEGEND.md)); этот кейс добавляет к нему более глубокое, честно обозначенное pet-понимание того, как устроена сама СУБД под капотом.