Резервный кластер
Patroni также поддерживает работу каскадной репликации на удалённый центр обработки данных (регион) с использованием функции, называемой «резервный кластер». Такие кластеры обладают следующими характеристиками:
- «резервный лидер», который ведёт себя примерно как обычный лидер кластера, за исключением того, что реплицирует данные с удалённого узла.
- каскадные реплики, которые реплицируют данные с резервного лидера.
Резервный лидер удерживает и обновляет блокировку лидера в DCS. Если блокировка лидера истекает, каскадные реплики проведут выборы для выбора другого лидера из резервных серверов.
Между резервным кластером и первичным кластером, от которого он воспроизводит данные, отсутствует какая-либо дополнительная связь, в частности, они не должны разделять один и тот же scope DCS, если используют один и тот же DCS. Они не знают друг о друге ничего, кроме информации репликации. Кроме того, резервный кластер не отображается в выводе patronictl_list или patronictl_topology на первичном кластере.
В целях гибкости вы можете указать методы создания реплики и восстановления WAL записей при работе кластера в резервном режиме, задав ключ create_replica_methods
в разделе standby_cluster
. Это отличается от создания реплик, когда кластер отсоединен и функционирует как обычный кластер, управление которым осуществляется с помощью create_replica_methods в разделе postgresql. Как «резервный», так и «обычный» create_replica_methods ссылаются на ключи в разделе postgresql.
Для настройки такого кластера необходимо указать раздел standby_cluster в конфигурации Patroni:
Примечание. Эти параметры будут применены только один раз при начальной инициализации кластера, и единственный способ изменить их позже — через DCS.
Patroni ожидает найти postgresql.conf или postgresql.conf.backup в PGDATA удалённого первичного сервера и не запустится, если не найдет его после выполнения basebackup. Если удалённый первичный сервер хранит свой postgresql.conf в другом месте, то копирование его в PGDATA является вашей ответственностью.
Если вы используете слоты репликации в резервном кластере, вы также должны создать соответствующий слот репликации в первичном кластере. Это не будет выполнено автоматически реализацией резервного кластера. Вы можете использовать функцию постоянных слотов репликации Patroni в первичном кластере для поддержания слота репликации с тем же именем, что и primary_slot_name, или со значением по умолчанию, если primary_slot_name не указано.
В случае, если удалённый сайт не предоставляет единый конечный пункт, подключающийся к первичному серверу, можно перечислить все хосты исходного кластера в разделе standby_cluster.host. Когда в standby_cluster.host указано несколько хостов, разделённых запятыми, Patroni будет:
- добавлять
target_session_attrs=read-writeвprimary_conninfoна узле резервного лидера. - использовать
target_session_attrs=read-writeпри попытке определить, нужно ли запускатьpg_rewind, или при выполненииpg_rewindна всех узлах резервного кластера. - Важно отметить, что для корректной работы
pg_rewindкластер должен быть инициализирован с использованиемdata page checksums(опция--data-checksumsдляinitdb) и/или значениеwal_log_hintsдолжно быть установлено вon. В противном случаеpg_rewindне будет работать должным образом.
Также существует возможность репликации резервного кластера из другого резервного кластера или из резервного участника первичного кластера: для этого необходимо указать один хост в разделе standby_cluster.host. Однако следует учитывать, что в этом случае pg_rewind не сможет выполниться в резервном кластере.
Имена участников (поле name в конфигурации Patroni каждого узла) должны быть уникальными во всём первичном кластере и во всех резервных кластерах, подключённых к нему.
Patroni устанавливает synchronous_standby_names на первичном сервере с использованием имён участников, которые также становятся application_name каждого соединения репликации в pg_stat_replication. Если узел резервного кластера имеет то же имя, что и участник первичного кластера, PostgreSQL увидит два соединения с одинаковыми значениями application_name. Такая неоднозначность может привести к тому, что PostgreSQL выполнит требование синхронной репликации с использованием соединения резервного кластера вместо намеченного участника первичного кластера, что вызовет преждевременное подтверждение транзакций как синхронно завершённых, хотя они не являются надёжно зафиксированными на правильном резервном сервере.
Это скрытый сбой: репликация продолжается, ошибки не регистрируются, но кластер фактически работает без валидного синхронного резервного сервера, что создаёт потенциальную угрозу потери данных при сбое первичного сервера.