# Часто задаваемые вопросы

> Часто задаваемые вопросы об эксплуатации Patroni и устранении неполадок.

---

Индекс LLMS: [llms.txt](/ru/llms.txt)

---

<a id="faq"></a>
В этом разделе приведены ответы на самые частые вопросы о Patroni. Каждый подраздел посвящён отдельной категории вопросов.

Надеемся, это прояснит большинство вопросов. Если сомнения остаются или возникла неожиданная проблема, инструкции по получению помощи и сообщению об ошибке приведены в разделах [общение](/ru/docs/patroni/contributing_guidelines#chatting) и [сообщение об ошибках](/ru/docs/patroni/contributing_guidelines#reporting_bugs).

--------

## Сравнение с другими решениями HA {#comparison-with-other-ha-solutions}

Почему Patroni требует отдельный кластер узлов DCS, а другие решения наподобие `repmgr` — нет?  
Решения HA можно реализовать разными способами, каждый со своими преимуществами и недостатками.

Программное обеспечение наподобие `repmgr` организует связь между узлами, чтобы решить, когда следует выполнить действия.

Patroni, напротив, опирается на состояние в DCS. Для Patroni DCS служит источником истины при выборе действий.

Отдельный кластер DCS усложняет архитектуру, но снижает вероятность расщепления кластера Postgres.

Чем Patroni отличается от других решений HA в управлении Postgres?  
Patroni управляет не только высокой доступностью кластера Postgres, но и самим Postgres.

Если узлов Postgres ещё нет, Patroni выполняет начальную инициализацию первичного и резервных узлов и управляет их конфигурацией Postgres. Если узлы уже существуют, Patroni принимает управление кластером.

Кроме того, Patroni поддерживает самовосстановление. При отказе первичного узла он не только переключается на реплику, но и пытается присоединить прежний первичный узел как реплику нового. Аналогично, при отказе реплики Patroni пытается присоединить её снова.

Поэтому Patroni называется «шаблоном решений HA». Он не ограничивается управлением физической репликацией, а управляет Postgres целиком.

--------

## DCS {#dcs}

Можно ли использовать один кластер `etcd` для данных двух или нескольких кластеров Patroni?  
Да.

Сведения о кластере Patroni хранятся в DCS по пути с префиксом из параметров Patroni `namespace` и `scope`.

Пока сочетания `namespace` и `scope` разных кластеров Patroni не конфликтуют, один кластер DCS может хранить сведения о нескольких кластерах Patroni.

Что произойдёт при использовании одного сочетания `namespace` и `scope` разными кластерами Patroni, подключёнными к одному DCS?  
Второй кластер Patroni не сможет управлять Postgres: в DCS уже будут сведения с тем же сочетанием, но несовместимым системным идентификатором Postgres. Из-за несовпадения Patroni прекращает управление вторым кластером, считая его другим кластером и конфигурацию пользователя ошибочной.

Для разных кластеров Patroni с общим DCS обязательно используйте разные `namespace` / `scope`.

Что произойдёт при потере кластера DCS?  
DCS в основном хранит состояние и динамическую конфигурацию кластера Patroni.

Первое последствие: все зависящие от этого DCS кластеры Patroni переходят в режим только для чтения, если не включён [dcs_failsafe_mode](/ru/docs/patroni/dcs_failsafe_mode#dcs_failsafe_mode).

Что делать при потере кластера DCS?  
Возможны три исхода:

1.  Кластер DCS полностью восстановлен: действия со стороны Patroni не требуются. После восстановления DCS Patroni также должен восстановиться;
2.  Кластер DCS пересоздан на прежнем месте с теми же конечными точками. Изменения со стороны Patroni не требуются;
3.  Создан новый кластер DCS с другими конечными точками. Нужно обновить конечные точки DCS в конфигурации каждого узла Patroni.

В сценарии `2.` или `3.` Patroni заново создаёт сведения о состоянии по текущему состоянию кластера и восстанавливает динамическую конфигурацию в DCS из резервного файла `patroni.dynamic.json`, хранящегося в каталоге данных Postgres каждого участника.

Что произойдёт при потере большинства в кластере DCS?  
DCS перестанет отвечать, и Patroni понизит текущий узел Postgres для чтения и записи.

Помните: при действиях с кластером Patroni опирается на состояние DCS.

Ситуацию можно смягчить с помощью [dcs_failsafe_mode](/ru/docs/patroni/dcs_failsafe_mode#dcs_failsafe_mode).

--------

## patronictl {#patronictl}

Нужно ли запускать [patronictl](/ru/docs/patroni/patronictl#patronictl) на узле Patroni?  
Нет.

Запускать [patronictl](/ru/docs/patroni/patronictl#patronictl) на узле Patroni удобно при наличии доступа: приложение [patronictl](/ru/docs/patroni/patronictl#patronictl) может использовать тот же файл конфигурации, что и агент `patroni`.

Однако [patronictl](/ru/docs/patroni/patronictl#patronictl) является клиентом и может запускаться на удалённых машинах. Достаточно настроить ему доступ к DCS и REST API участников Patroni.

Почему сведения об одном участнике Patroni исчезли из вывода команды [patronictl_list](/ru/docs/patroni/patronictl#patronictl_list)?  
Вывод [patronictl_list](/ru/docs/patroni/patronictl#patronictl_list) основан на содержимом DCS.

Если сведения об участнике исчезли из DCS, вероятнее всего агент Patroni на этом узле больше не работает или не может связаться с DCS.

Поскольку участник не обновляет сведения, они в итоге истекают в DCS, и участник больше не показывается в выводе [patronictl_list](/ru/docs/patroni/patronictl#patronictl_list).

Почему сведения об одном участнике Patroni в выводе команды [patronictl_list](/ru/docs/patroni/patronictl#patronictl_list) неактуальны?  
Вывод [patronictl_list](/ru/docs/patroni/patronictl#patronictl_list) основан на содержимом DCS.

По умолчанию Patroni обновляет эти сведения примерно каждые `loop_wait` секунд. Даже при нормальной работе данные в DCS могут «задерживаться» до `loop_wait` секунд.

Однако это не строгое правило: некоторые операции Patroni немедленно обновляют сведения в DCS.

--------

## Конфигурация {#configuration}

Чем различаются динамическая и локальная конфигурации?  
Динамическая, или глобальная, конфигурация хранится в DCS и применяется ко всем участникам кластера Patroni. В основном конфигурацию следует хранить именно там.

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

Подробнее см. в разделе [конфигурация](/ru/docs/patroni/config#config).

Какие типы конфигурации есть в Patroni и каков их приоритет?  
Доступны следующие типы:

- Динамическая конфигурация: применяется ко всем участникам;
- Локальная конфигурация: применяется к локальному участнику и переопределяет динамическую;
- Конфигурация окружения: применяется к локальному участнику и переопределяет динамическую и локальную конфигурации.

**Примечание:** некоторые GUC Postgres можно задать только глобально, то есть через динамическую конфигурацию. Кроме того, для части GUC Patroni принудительно устанавливает жёстко заданное значение.

Подробнее см. в разделе [конфигурация](/ru/docs/patroni/config#config).

Есть ли средство для создания файла конфигурации Patroni?  
Да.

Команды `patroni --generate-sample-config` и `patroni --generate-config` создают соответственно пример конфигурации Patroni и конфигурацию на основе существующего экземпляра Postgres.

Подробнее см. [generate_sample_config](/ru/docs/patroni/config#generate_sample_config) и [generate_config](/ru/docs/patroni/config#generate_config).

Я изменил параметры в `bootstrap.dcs`, но Patroni не применяет их к участникам. В чём проблема?  
Значения `bootstrap.dcs` используются только при начальной инициализации нового кластера и записываются в DCS во время неё.

После завершения начальной инициализации динамическую конфигурацию можно изменять только через DCS.

Подробнее см. следующий вопрос.

Как изменить динамическую конфигурацию?  
Нужно изменить конфигурацию в DCS одним из способов:

- [patronictl_edit_config](/ru/docs/patroni/patronictl#patronictl_edit_config); либо
- запрос `PATCH` к [config_endpoint](/ru/docs/patroni/rest_api#config_endpoint).

Как изменить локальную конфигурацию?  
Измените файл конфигурации соответствующего участника Patroni и отправьте агенту Patroni сигнал `SIHGUP`. Это можно сделать одним из способов:

- отправить запрос `POST` к REST API [reload_endpoint](/ru/docs/patroni/rest_api#reload_endpoint); либо

- выполнить [patronictl_reload](/ru/docs/patroni/patronictl#patronictl_reload); либо

- локально отправить процессу Patroni сигнал `SIGHUP`:

  > - Если Patroni запущен через systemd, используйте `systemctl reload PATRONI_UNIT.service`, где `PATRONI_UNIT` — имя службы Patroni; либо
  > - Если Patroni запущен иначе, найдите процесс `patroni` и выполните `kill -s HUP PID`, где `PID` — идентификатор процесса `patroni`.

**Примечание:** в некоторых случаях перезагрузка через [patronictl_reload](/ru/docs/patroni/patronictl#patronictl_reload) может не сработать:

- Истёкшие сертификаты REST API: проблему можно смягчить параметром `-k` команды [patronictl](/ru/docs/patroni/patronictl#patronictl);
- Неверные учётные данные: например, когда в файле конфигурации изменены учётные данные `restapi` или `ctl`, а один файл используется для Patroni и [patronictl](/ru/docs/patroni/patronictl#patronictl).

Как изменить конфигурацию окружения?  
Patroni читает конфигурацию окружения только при запуске.

Поэтому после изменения конфигурации окружения соответствующий агент Patroni необходимо перезапустить.

Не допустите переключения при отказе в кластере. Возможно, пригодится [patronictl_pause](/ru/docs/patroni/patronictl#patronictl_pause).

Как сократить повторяющиеся строки сигналов активности в журнале при нормальной работе?

Если журнал засорён повторяющимися строками наподобие `Lock owner: ...` и `no action. I am ...`, задайте `log.deduplicate_heartbeat_logs: true`.

Параметр задаётся в файле YAML Patroni ([настройки журнала](/ru/docs/patroni/config/yaml#log_settings)) либо через `PATRONI_LOG_DEDUPLICATE_HEARTBEAT_LOGS=true`.

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

Что произойдёт при изменении GUC Postgres, требующего перезагрузки конфигурации?  
При изменении динамической или локальной конфигурации описанным выше способом Patroni сам перезагрузит конфигурацию Postgres.

Что произойдёт при изменении GUC Postgres, требующего перезапуска?  
Patroni отметит затронутых участников флагом `pending restart`.

Время и способ перезапуска участников определяет пользователь. Доступны следующие варианты:

- [patronictl_restart](/ru/docs/patroni/patronictl#patronictl_restart); либо
- запрос `POST` к [restart_endpoint](/ru/docs/patroni/rest_api#restart_endpoint).

**Примечание:** некоторые GUC Postgres требуют особого порядка перезапуска узлов. Подробнее см. [shared_memory_gucs](/ru/docs/patroni/config#shared_memory_gucs).

Чем различаются `etcd` и `etcd3` в конфигурации Patroni?  
`etcd` использует API версии 2 `etcd`, а `etcd3` — API версии 3 `etcd`.

Сведениями, сохранёнными через API версии 2, нельзя управлять через API версии 3, и наоборот.

Рекомендуется настраивать `etcd3` вместо `etcd`, поскольку:

- API версии 2 по умолчанию отключён начиная с Etcd v3.4;
- API версии 2 будет полностью удалён в Etcd v3.6.

В конфигурации Patroni включён `use_slots`, но когда участник некоторое время находится вне сети, его слот репликации удаляется на вышестоящем узле. Как этого избежать?  
Доступны два варианта:

1.  Настроить `member_slots_ttl` (по умолчанию `30min`, доступно начиная с Patroni `4.0.0` и PostgreSQL 11). Слоты отсутствующих участников не удаляются, если простой короче заданного порога.
2.  Настроить для участников постоянные физические слоты репликации.

Начиная с Patroni `3.2.0` слоты участников могут быть постоянными слотами под управлением Patroni.

Patroni создаёт постоянные физические слоты на всех узлах, не удаляет их и продвигает LSN слотов на всех узлах в соответствии с LSN, использованным участником.

Если позднее соответствующий участник удаляется, **пользователь обязан** скорректировать конфигурацию постоянных слотов, иначе Patroni сохранит их навсегда.

**Примечание:** в версиях Patroni старше `3.2.0` слоты участников также можно настроить как постоянные физические, но управляются они только на текущем лидере. При аварийном или плановом переключении слоты создаются на новом лидере без гарантии, что у него есть все сегменты WAL для отсутствующего узла.

**Примечание:** даже в Patroni `3.2.0` возможна небольшая гонка. Сразу после создания слот на реплике может опережать тот же слот лидера, а если слот никто не использует, после переключения часть файлов может отсутствовать. Поэтому рекомендуется настроить непрерывное архивирование, позволяющее восстановить необходимые WAL или выполнить PITR.

Чем различаются `loop_wait`, `retry_timeout` и `ttl`?  
Patroni периодически выполняет так называемый цикл HA. В каждом цикле он проверяет работоспособность кластера и в зависимости от состояния может предпринимать действия, например переключаться на резервный сервер.

`loop_wait` определяет в секундах, сколько Patroni ждёт до следующего цикла проверок HA.

`retry_timeout` задаёт тайм-аут повторных операций с DCS и Postgres. Например, если DCS не отвечает более `retry_timeout` секунд, Patroni может в целях безопасности понизить первичный узел.

`ttl` задаёт срок аренды блокировки `leader` в DCS. Если текущий лидер не может обновить аренду в циклах HA дольше `ttl`, аренда истекает и запускает в кластере `leader race`.

**Примечание:** при изменении параметров учитывайте, что Patroni применяет правило и минимальные значения из раздела [динамическая конфигурация](/ru/docs/patroni/config/dynamic#dynamic).

--------

## Управление Postgres {#postgres-management}

Можно ли менять GUC Postgres непосредственно в конфигурации Postgres?  
Можно, но этого следует избегать.

Конфигурацией Postgres управляет Patroni, поэтому попытки редактировать файлы могут оказаться бесполезными: Patroni способен их перезаписать.

Управление Patroni можно обойти несколькими способами:

- изменять GUC Postgres через `$PGDATA/postgresql.base.conf`; либо
- определить `postgresql.custom_conf`, используемый вместо `postgresql.base.conf`, и управлять им извне; либо
- изменять GUC с помощью `ALTER SYSTEM` / `ALTER DATABASE` / `ALTER USER`.

Подробнее см. раздел [important_configuration_rules](/ru/docs/patroni/config#important_configuration_rules).

В любом случае рекомендуется управлять всей конфигурацией Postgres через Patroni. Это централизует управление и упрощает отладку Patroni.

Можно ли перезапускать узлы Postgres напрямую?  
Нет, **не следует** пытаться управлять Postgres напрямую.

Перезапуск сервера Postgres в обход Patroni может вызвать переключение в кластере.

Управляйте сервером Postgres только предоставленными Patroni способами.

Может ли Patroni принять управление существующим кластером Postgres?  
Да.

Подробные инструкции приведены в [existing_data](/ru/docs/patroni/existing_data#existing_data).

Как Patroni управляет Postgres?  
Patroni запускает и останавливает Postgres, выполняя двоичные файлы Postgres, такие как `pg_ctl` и `postgres`.

Поэтому **ОБЯЗАТЕЛЬНО** отключите все другие средства управления кластерами Postgres, например модули systemd вроде `postgresql.service`. Только Patroni должен запускать, останавливать и повышать экземпляры Postgres в кластере. Иначе возможно расщепление: например, если первичный узел отказал, включённый модуль `postgresql.service` может снова запустить Postgres и вызвать расщепление.

--------

## Концепции и требования {#concepts-and-requirements}

Какие приложения входят в Patroni?  
Patroni поставляет два основных приложения:

- `patroni`: агент Patroni, управляющий узлом Postgres;
- [patronictl](/ru/docs/patroni/patronictl#patronictl): утилита командной строки для взаимодействия с кластером Patroni — плановых переключений, перезапусков, изменений конфигурации и т. д. Подробнее см. [patronictl](/ru/docs/patroni/patronictl#patronictl).

Что такое `standby cluster` в Patroni?  
Это кластер без работающего первичного узла Postgres, то есть без участника для чтения и записи.

Такие кластеры реплицируют данные из другого кластера и обычно полезны для репликации между центрами обработки данных.

Лидером кластера является резервный сервер, реплицирующий изменения с удалённого узла Postgres. Остальные резервные серверы настраиваются на каскадную репликацию от этого лидера.

**Примечание:** резервный кластер ничего не знает об исходном кластере, с которого реплицируется. Он может использовать `restore_command` вместо потоковой передачи WAL и совершенно независимый кластер DCS.

Подробнее см. [standby_cluster](/ru/docs/patroni/standby_cluster#standby_cluster).

Что такое `leader` в Patroni?  
`leader` в Patroni — своего рода координатор кластера.

В обычном кластере Patroni `leader` является узлом для чтения и записи.

В резервном кластере Patroni `leader`, также называемый `standby leader`, реплицирует данные с удалённого узла Postgres и каскадно передаёт изменения остальным участникам резервного кластера.

Требует ли Patroni минимального количества узлов Postgres в кластере?  
Нет, Patroni может работать с любым количеством узлов Postgres.

Помните: Patroni отделён от DCS.

Что означает [пауза](/ru/docs/patroni/pause#pause) в Patroni?  
Пауза — операция Patroni, позволяющая пользователю временно ослабить управление Postgres.

Это особенно полезно при обслуживании кластера, когда нужно предотвратить решения Patroni, связанные с HA, например переключение на резервный сервер при остановке первичного.

Подробнее см. [пауза](/ru/docs/patroni/pause#pause).

--------

## Автоматическое переключение при отказе {#automatic-failover}

Как работает механизм автоматического переключения Patroni?  
Автоматическое переключение Patroni основано на механизме `leader race`.

Patroni хранит состояние кластера в DCS, включая блокировку `leader` с именем участника Patroni, являющегося текущим `leader` кластера.

Блокировка `leader` имеет срок жизни. Если узел `leader` не обновляет её аренду вовремя, ключ в итоге истекает в DCS.

Истечение блокировки `leader` запускает `leader race`: все узлы выполняют проверки, определяя лучшего кандидата на роль `leader`. Часть проверок включает обращения к REST API всех остальных участников Patroni.

Все участники Patroni, считающие себя лучшим кандидатом, пытаются получить блокировку `leader`. Первый получивший блокировку `leader` участник повышает себя до узла чтения и записи либо `standby leader`, а остальные настраиваются следовать за ним.

Можно ли временно отключить автоматическое переключение в кластере Patroni?  
Да.

Для этого временно приостановите кластер. Обычно это полезно при обслуживании.

Чтобы возобновить автоматическое переключение, снимите кластер с паузы.

Подробнее см. [пауза](/ru/docs/patroni/pause#pause).

--------

## Начальная инициализация и создание резервных серверов {#bootstrapping-and-standbys-creation}

Как Patroni создаёт первичный и резервный узлы Postgres?  
По умолчанию Patroni использует `initdb` для начальной инициализации нового кластера и `pg_basebackup` для создания резервных узлов из копии участника `leader`.

Поведение можно настроить пользовательскими методами начальной инициализации и создания реплик.

Пользовательские методы обычно полезны для восстановления копий, созданных инструментами наподобие pgBackRest или Barman.

Подробнее см. [custom_bootstrap](/ru/docs/patroni/replica_bootstrap#custom_bootstrap) и [custom_replica_creation](/ru/docs/patroni/replica_bootstrap#custom_replica_creation).

--------

## Мониторинг {#monitoring}

Как отслеживать кластер Patroni?  
Patroni предоставляет несколько удобных конечных точек в [rest_api](/ru/docs/patroni/rest_api#rest_api):

- `/metrics`: предоставляет метрики мониторинга в формате для Prometheus;
- `/patroni`: предоставляет состояние кластера в формате JSON. Сведения очень похожи на вывод конечной точки `/metrics`.

Эти конечные точки можно использовать для проверок мониторинга.
