PgPool-II: что ломается при отказе узла базы данных
Основной узел базы перестаёт отвечать в самый неудачный момент — например, ночью, когда дежурный инженер узнаёт об этом из системы оповещений. Приложение в этот момент держит открытые соединения к отказавшему узлу, а не к резерву: пул ещё не перестроен, маршрутизация не переключена. Записи и заказы начинают падать с ошибкой соединения, а необработанные запросы копятся в очереди.
Дальше начинается ручная работа. Резервный узел нужно перевести в режим записи, переключить на него трафик, убедиться, что реплика догнала основной по журналу, и только потом вернуть приложение к работе. Пока это происходит, часть запросов теряется безвозвратно — их никто не переиграет, потому что очередь уже разошлась по клиентам и распалась на уровне соединения.
PgPool-II ставится между приложением и базой именно для того, чтобы этот сценарий не разворачивался вручную. Он держит собственный пул соединений, периодическими проверками следит за состоянием узлов и при отказе сам исключает упавший узел из маршрутизации, а резервный переводит в режим записи. Приложение продолжает получать соединение из пула — для сервиса меняется адрес назначения, а не сам факт доступности базы.
Но присутствие PgPool-II в схеме само по себе не убирает точку отказа. Если он запущен в одном экземпляре, без резервирования самого пула и без выверенных таймаутов проверки, отказ просто переезжает с базы на него. Ниже разбираем, как это закрывается.
Что даёт отказоустойчивый кластер баз данных
Отказоустойчивость проявляется не в спокойной работе, а в первые секунды после сбоя. Поэтому смотрим не на заявленную поддержку репликации, а на шкалу времени: как быстро балансировщик замечает упавший узел, кто переключает трафик и что в этот момент видит приложение.
Приложение подключается к одному адресу, а PgPool-II распределяет входящие соединения между серверами. Проверка доступности идёт с коротким интервалом: после нескольких неудачных откликов узел исключается из выдачи, оставшиеся принимают его трафик. Ошибок соединения на стороне приложения нет — меняется только внутренняя маршрутизация, а время восстановления измеряется секундами вместо ручного разбора.
Дальше включается разделение чтения и записи: запросы на выборку уходят на реплики, изменяющие — на основной узел. Приложение об этом не знает, строка подключения и код остаются прежними. На типовой нагрузке на реплики уходит до двух третей обращений, и основной узел перестаёт быть единственной точкой и по нагрузке, и по отказам.
Предсказуемость здесь важнее пиковой производительности. Деградация одного узла превращается в событие с известным сценарием: часть запросов замедляется, но сервис остаётся доступным. Класс отказов «упал сервер — лежит весь продукт» уходит из перечня рисков, а поведение кластера проверяется на учениях, а не выясняется в момент реальной аварии.
Режимы работы PgPool-II и их ограничения
Отказоустойчивый контур на PgPool-II собирают несколькими способами, и балансировщик нужен не всегда. Ключевой вопрос — что именно требуется: переживать отказ основного узла, распределять читающую нагрузку или гасить всплески коротких подключений. От этого зависит, где встанет PostgreSQL, а где — промежуточный слой.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Потоковая репликация горячего резерва без балансировщика | Один основной узел и резерв, чтение с резерва, переключение по регламенту | Автоматического переключения при отказе нет; адреса узлов прописаны в конфигурации приложения |
| PgPool-II в режиме репликации запросов | Единый адрес для приложения и автоматическое переключение при отказе | Без сторожевого модуля возможно расщепление кластера при обрыве связи; чтение с реплик отстаёт |
| PgPool-II как балансировщик соединений | Много коротких подключений, всплески, жёсткий лимит соединений на сервере | Отказоустойчивости не даёт — только удержание и перераспределение соединений |
| Логическая репликация выборочных таблиц | Перенос между мажорными версиями, вынос части данных на отдельный контур | Нет автоматического переключения, задержка выше, состав объектов должен совпадать |
Что проверить перед выбором
Режим репликации запросов не снимает ограничений самой СУБД: запросы, чувствительные к актуальности данных, маршрутизируются на основной узел, а расширения должны стоять на всех узлах. Совместимость проверяют на пиковой нагрузке — задержку репликации, поведение при обрыве канала и корректный возврат старого основного узла в строй.
Как мы внедряем отказоустойчивый кластер: этапы работ
Кластер высокой доступности собирается не «на живую», а по последовательности, где каждый шаг подтверждается проверкой. Ниже — порядок работ, по которому мы ведём проект: от аудита до передачи смене заказчика. На каждом этапе видно, что уже сделано, чем это проверено и какие риски остались открытыми.
- Аудит текущей схемы и точек отказа. Разбираем контур как есть: где проходит запись, кто держит соединения, как устроена репликация. Выписываем единые точки — один узел записи, балансировщик без резерва, ручной перевод при сбое — и оцениваем цену простоя каждой.
- Проектирование контура. Фиксируем роли узлов (ведущий, резервный, узлы чтения), схему потоков данных между PgPool-II, серверами баз и приложениями, правила маршрутизации запросов на чтение и запись, режим распределения нагрузки.
- Настройка узлов и проверка переключения. Поднимаем пул соединений, репликацию, проверки живости и автоматическое переключение ролей. Отдельно проверяем, что приложение переживает смену ведущего узла без правок в коде.
- Испытания отказом на стенде. По очереди выводим из строя каждый узел и связь между площадками: смотрим время переключения, поведение очереди запросов и то, какие транзакции теряются, а какие нет.
- Прогон под нагрузкой. Подаём профиль, близкий к рабочему: пиковые соединения, тяжёлые отчёты, длинные транзакции. Проверяем, что переключение укладывается в согласованное окно и под нагрузкой.
- Передача в эксплуатацию и обучение смены. Отдаём конфигурации, схему ролей и потоков, регламент переключения и разбора сбоев. Проводим учения со сменой заказчика, чтобы перевод узлов делался по инструкции, а не по памяти.
Конфигурации, схемы и регламенты: артефакты внедрения
Внедрение считается закрытым не когда узлы поднялись, а когда у заказчика остаётся комплект артефактов, по которому контур можно сопровождать своими силами. Часть файлов уходит в репозиторий конфигураций, часть — в базу знаний дежурной смены. Ниже — что именно передаём.
- Рабочие конфигурации отказоустойчивого контура — файлы PgPool-II, узлов репликации и менеджера кластера с параметрами под ваш профиль нагрузки, а не демонстрационные. Хранятся под контролем версий, чтобы настройку можно было откатить, а не восстанавливать по памяти.
- Схема контура — актуальная топология: роли узлов, маршруты трафика, точки отказа и порядок их прохождения. Обновляется при каждом изменении, а не живёт в голове одного инженера.
- Правила доступа и роли — матрица прав на узлы, режимные функции балансировщика и мониторинг; отдельные учётки для дежурного и для автоматизации, разделение чтения и изменения.
- Регламент переключения — пошаговый сценарий планового и аварийного перевода ролей, с ожидаемым временем, критериями «пора вмешиваться» и порядком возврата узлов в строй.
- Инструкция по восстановлению узла — что делать при отставании или выпадении реплики: проверка синхронности, условия догона без полного пересоздания, команды для типовых сбоев.
- Наблюдаемость и оповещения о сбоях — набор метрик (отставание реплик, состояние узлов, доля ошибок маршрутизации) с порогами, при которых дежурный получает сигнал, а не узнаёт о сбое из жалоб.
- Записи учений — фактическое время восстановления по итогам тренировок и список правок, внесённых в регламент после каждой.
Кейс: простой при отказе узла сократился в разы
Исходная схема и её слабые места
Сервис с постоянным потоком записей держался на одном основном узле и горячем резерве, а переключение выполнял дежурный инженер вручную. При отказе основного узла приложение получало ошибки записи, пока резерв не поднимали и не перенаправляли трафик: простой доходил до десятков минут, а часть незавершённых транзакций разбирали и повторяли руками. Слабое место было не в самом резерве, а в отсутствии автоматического арбитра — решение о переходе принимал человек по косвенным признакам и с задержкой.
Что изменили и что показали метрики
Перед кластером поставили PgPool-II: он держит пул соединений, периодически опрашивает узлы и сам инициирует переключение на резерв, когда основной перестаёт отвечать. Доля автоматических переключений выросла с нуля почти до всех отказов, которые фиксирует мониторинг; ручной разбор остался только для сценариев с потерей сети между узлами, где нужно осознанное решение.
Простой при отказе узла сократился в разы: переключение укладывается в секунды, приложение переподключается к новому основному узлу, а не ждёт инженера. Пул соединений снял нагрузку на базу под пиками — приложение больше не открывает лавину новых подключений на каждый всплеск, и очередь запросов перестала упираться в лимит соединений.
Чем отличается балансировка соединений от репликации
Репликация и балансировка решают разные задачи, и путать их дорого. Репликация отвечает за то, чтобы копия данных существовала на другом узле: основной узел передаёт изменения потоком, резервный применяет их и доступен только на чтение. Балансировка отвечает за маршрут запроса — на какой узел он уйдёт и что произойдёт с ним в момент отказа.
Настроив потоковую репликацию, нагрузку чтения вы не распределите. Реплика получает те же данные, но приложение обращается к основному узлу, пока между ним и базами нет маршрутизатора. PgPool-II работает здесь: разбирает запрос, изменения отправляет на основной узел, чтение раскладывает по репликам и держит пул соединений.
Схему выбирают по профилю нагрузки. Если преобладают записи, реплики основной узел не разгрузят — они лишь повторяют изменения. Если доминирует чтение, распределение запросов чтения снимает с основного узла заметную долю обращений, но приложение должно мириться с отставанием реплики.
Отсюда главный риск: пока узлы расходятся, реплика отдаёт устаревшие данные — пользователь не видит только что сохранённую запись. Обратная ошибка хуже: изменение уходит на узел, который маршрутизатор ошибочно считает основным.
Тогда расходятся уже сами узлы, и это не лечится перезапуском. Поэтому рядом с балансировкой идут проверки состояния узлов, автоматическое переключение на резервный и защита от расщепления кластера. Что делать при отставании — ждать, исключать реплику из распределения или переводить чтение на основной узел — решают заранее.
Технические сомнения перед внедрением: разбор
Перед внедрением PgPool-II у команды всплывают одни и те же сомнения: придётся ли править приложение, нужен ли простой, сработает ли автоматическое переключение, что делать при расхождении данных.
Приложение придётся переписывать?
Нет. PgPool-II встаёт между приложением и кластером и говорит на том же протоколе, что обычный сервер баз данных. Меняется только строка подключения — драйверы и библиотеки доступа к данным продолжают работать. Точечно проверяем запросы, завязанные на одном узле: последовательности и серверные курсоры.
Внедрение на работающем кластере — это простой?
Простой не нужен. PgPool-II поднимается рядом с текущим кластером; сначала переводим на него чтение и смотрим поведение под нагрузкой, запись — последней. На это нужна пауза в секунды, чтобы закрылись открытые транзакции. Откат — возврат приложений на прежнюю строку подключения.
Как проверить автоматическое переключение?
На стенде, приближенном к боевому: останавливаем основной узел и фиксируем время до перевода реплики в основной, число потерянных транзакций, поведение приложения при разрыве соединения. Затем повторяем на репетиции боевого контура — с отчётом и логами.
Что будет при расхождении данных?
PgPool-II следит за отставанием реплик: при превышении порога узел исключается из выдачи чтения — приложение не получает устаревшие данные. Узел, выпавший после сбоя, пересобирается из копии основного. Задержка репликации, доступность и смена роли выводятся на панель мониторинга: алерт приходит раньше, чем проблему заметят пользователи.
Обсудим задачу и вернёмся с планом работ
Чтобы оценка опиралась на факты, а не на предположения, для старта достаточно описания текущей схемы и характера нагрузки. Мы разберём, где сейчас точка отказа, как распределяются чтение и запись между узлами и готова ли единая точка входа для приложений.
От заказчика нужно немногое:
- Схема контура: число узлов PostgreSQL, наличие реплик, режим репликации, кто сейчас управляет сменой роли основного узла.
- Профиль нагрузки: доля чтения и записи, пиковые периоды, требования к времени ответа на запрос.
- Поведение приложений: как переживают разрыв соединения, используют ли единый адрес подключения, готовы ли корректно повторить запрос после переключения.
- Парк соединений: сколько клиентов подключается одновременно и есть ли пул на стороне приложения.
- Требования к отказу: допустимое время недоступности на запись и на чтение, нужен ли автоматический возврат роли на прежний узел.
- Регламенты: окно обслуживания, доступы к серверам и к системам мониторинга.
По итогам обсуждения присылаем план внедрения: состав и порядок работ, этапность (подготовка узлов, включение распределения чтения, проверка переключения роли, нагрузочная проверка), критерии приёмки и порядок передачи с сопровождением. Опишите задачу — вернёмся с оценкой и планом.







