Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Репликация, пулы соединений и итоговый проект
advanced_topics

Репликация, пулы соединений и итоговый проект

Физическая и логическая репликация, переключение, PgBouncer и исходящая очередь

Открыть лабораториюv1.1.0Запускается локально из публичного репозитория

Репликация, пулы соединений и итоговый проект

Последний урок связывает эксплуатационные механизмы. Он не предполагает, что вы уже администратор: каждый новый термин сначала получает простое определение, а затем ограничения.

Высокая доступность — способность продолжить работу после отказа узла за оговорённое время и с допустимой потерей данных. Одной резервной копии сервера для этого мало. Нужен проверенный порядок переключения и защита от двух одновременно пишущих ведущих узлов.

#Секции таблицы как жизненный цикл

Секционированная таблица выглядит для запросов как одна, но хранит строки в отдельных физических таблицах по диапазонам:

CREATE TABLE app_events ( id bigint GENERATED ALWAYS AS IDENTITY, org_id bigint NOT NULL, occurred_at timestamptz NOT NULL, payload jsonb NOT NULL, PRIMARY KEY (id, occurred_at) ) PARTITION BY RANGE (occurred_at); CREATE TABLE app_events_2026_07 PARTITION OF app_events FOR VALUES FROM ('2026-07-01 00:00+00') TO ('2026-08-01 00:00+00'); CREATE TABLE app_events_default PARTITION OF app_events DEFAULT;

Если WHERE содержит совместимое условие по occurred_at, PostgreSQL отбрасывает лишние секции. Это называется исключением секций (partition pruning). Запрос без ключа может читать их все.

Секции также упрощают срок хранения: заранее создать следующий месяц, отсоединить старый, архивировать его и удалить позже. Операции ATTACH, DETACH и DROP всё равно требуют плана блокировок. Секцию по умолчанию нужно проверять, чтобы в ней не копились строки будущих диапазонов.

#Физическая потоковая репликация

Репликация — поддержание копии данных на другом сервере. При физической репликации ведущий сервер (primary) передаёт WAL, а резервный (standby) записывает и воспроизводит его. Резервный хранит копию всего кластера совместимой основной версии, а не выбранные таблицы.

Состояние отправки видно на ведущем:

SELECT application_name, client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn, pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_lag_bytes FROM pg_stat_replication;

Позиции означают:

  • sent_lsn — сколько WAL отправлено;
  • write_lsn — сколько записано на резервном сервере;
  • flush_lsn — сколько надёжно сохранено там;
  • replay_lsn — сколько уже применено к его данным.

Время отставания без новых транзакций может быть пустым или вводить в заблуждение. Смотрите также разницу в байтах, скорость WAL и задержку приложения.

#Асинхронная и синхронная репликация

При асинхронной репликации ведущий может подтвердить COMMIT до надёжного получения WAL резервным узлом. Если ведущий потерян, несколько последних подтверждённых транзакций могут исчезнуть.

При синхронной репликации фиксация ждёт выбранный резервный сервер:

synchronous_standby_names = 'ANY 1 (standby_a, standby_b)' synchronous_commit = on

Режим on ждёт надёжной записи на синхронном резервном узле. remote_apply дополнительно ждёт применения WAL. Это уменьшает возможную потерю, но увеличивает задержку. Если обязательные резервные узлы недоступны, фиксации могут остановиться.

Настройка не решает выбор правильного узла при аварии и не предотвращает двойную запись сама по себе.

#Переключение и изоляция старого ведущего

Переключение при отказе (failover) — назначение резервного узла новым ведущим. Ограждение (fencing) — гарантия, что старый ведущий больше не может принимать запись.

До переключения система должна доказать:

  1. старый ведущий остановлен или изолирован от клиентов и хранилища;
  2. выбранный резервный узел подходит под RPO;
  3. только один управляющий участник имеет право назначить ведущего;
  4. клиенты переключаются после проверки сервера и контрольных данных;
  5. старый узел не возвращается без повторной настройки или сверки.

Если два ведущих принимают изменения независимо, возникает раздвоение кластера (split brain). Простая проверка TCP-порта не доказывает, что старый узел перестал писать.

Регулярная тренировка отказа измеряет RTO, потерянные и повторные операции, переподключение клиентов и поведение приложения.

#Логическая репликация

Логическая репликация передаёт изменения выбранных таблиц в виде логических операций. На источнике создаётся публикация, на получателе — подписка:

CREATE PUBLICATION marketplace_pub FOR TABLE marketplace.orders, marketplace.payments; CREATE SUBSCRIPTION marketplace_sub CONNECTION 'host=primary.internal dbname=course user=replicator sslmode=verify-full passfile=/run/secrets/replication.pgpass' PUBLICATION marketplace_pub;

Пароль не записывают в урок или репозиторий. Защищённый файл доставляет система секретов.

Встроенная логическая репликация не переносит автоматически DDL, роли и текущее значение последовательностей. Нужны совместимая структура, идентификатор строки для UPDATE и DELETE, правила конфликтов, наблюдение и план начального копирования.

Она помогает переходить между основными версиями, но нулевой простой требует отдельной репетиции переключения.

#Слоты репликации

Слот репликации хранит позицию получателя и удерживает нужный ему WAL:

SELECT slot_name, slot_type, active, restart_lsn, confirmed_flush_lsn, pg_size_pretty( pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) ) AS retained_wal FROM pg_replication_slots;

Если получатель остановился, удерживаемый WAL может заполнить диск ведущего. Оповещение учитывает скорость роста и свободное место. Удаление слота теряет позицию и требует согласованного восстановления получателя.

#PgBouncer и повторное использование соединений

Пул соединений держит ограниченное число подключений к PostgreSQL и обслуживает большее число клиентов.

  • В режиме сеансов серверное соединение закреплено за клиентом до отключения. Сеансовые настройки сохраняются, но экономия соединений меньше.
  • В режиме транзакций соединение возвращается в пул после COMMIT или ROLLBACK. Следующая транзакция клиента может попасть в другой процесс.

Для пула транзакций проверьте код на сеансовый SET, временные таблицы, сеансовые рекомендательные блокировки, LISTEN/NOTIFY и ожидания драйвера от подготовленных запросов.

[pgbouncer] pool_mode = transaction auth_type = scram-sha-256 max_client_conn = 1000 default_pool_size = 20 server_connect_timeout = 5 query_wait_timeout = 10

Эти числа — пример для нагрузочного опыта, а не универсальная настройка. Для очереди пула нужны метрики ожидания и отказов. В недоверенной сети используют TLS и управляемое хранилище секретов.

#Изменение базы и отправка сообщения

Репликация не делает атомарными изменение таблицы и отправку в брокер сообщений. Транзакционная исходящая очередь записывает бизнес-изменение и будущее событие в одной транзакции:

BEGIN; INSERT INTO payment_inbox (external_id, org_id, order_id, amount) VALUES ($1, $2, $3, $4) ON CONFLICT (external_id) DO NOTHING RETURNING external_id; UPDATE orders SET status = 'paid' WHERE id = $3 AND org_id = $2; INSERT INTO outbox (topic, payload) VALUES ('payment.accepted', jsonb_build_object('order_id', $3)); COMMIT;

В полном варианте заказ и исходящее событие меняются только если входящее событие действительно добавлено. Отдельный процесс читает outbox и публикует сообщение после COMMIT.

Отправитель может повторить публикацию после сбоя между отправкой и отметкой published_at, поэтому получатель тоже должен обрабатывать повторы по ключу идемпотентности.

#Практика и итоговый проект

В лаборатории 28 вы свяжете входящее событие, изменение заказа и исходящую очередь.

Итоговый проект объединяет модель данных, идемпотентность, транзакции, планы, индексы, RLS, миграцию, секции, восстановление, пул соединений и отказоустойчивость. Файлы rubric.md и evidence-template.md перечисляют проверяемые результаты.

Пример модуля показывает только минимальную связь входящего события, заказа и исходящего события. Решения по ёмкости, безопасности, копиям и аварийной инструкции нужно обосновать отдельно.

Подробнее: резервный сервер, синхронная репликация, логическая репликация, секционирование.