27.1. Архитектура #
Благодаря встроенным возможностям отказоустойчивости Postgres Pro позволяет создать кластер с одним узлом-лидером и нескольмими узлами-последователями. Лидер является ведущим сервером BiHA-кластера, а последователи — репликами лидера.
Утилита bihactl позволяет инициализировать кластер и создавать узел-лидер, добавлять узлы-последователи, преобразовывать существующий узел в узел-лидер или узел-последователь в BiHA-кластере, а также проверять статус узлов кластера. Лидер доступен для чтения и записи, в то время как последователи доступны только для чтения и реплицируют данные с лидера в синхронном или асинхронном режиме.
Физическая потоковая репликация, реализованная в BiHA , обеспечивает отказоустойчивость, защищая от отказов серверов и системы хранения данных. При физической репликации файлы WAL узла-лидера синхронно или асинхронно отправляются на узел-последователь и применяются на нём. При синхронной репликации для каждой фиксации транзакции пользователь ожидает подтверждения от узла-последователя. Узел-последователь BiHA-кластера может использоваться для выполнения следующих задач:
Выполнение читающих транзакций в базе данных.
Подготовка отчётов.
Создание таблиц в оперативной памяти для пишущих транзакций.
Подготовка резервной копии узла-последователя.
Восстановление повреждённых блоков данных на узле-лидере путём получения этих блоков с узла-последователя.
Проверка повреждённых записей в файлах WAL.
Физическая потоковая репликация, реализованная в BiHA, обеспечивает защиту от следующих видов отказов:
Отказ узла-лидера. В этом случае статус узла-последователя повышается, и он становится новым лидером кластера. Повышение выполняется либо вручную с помощью функции biha.set_leader, либо автоматически с помощью выборов.
Отказ узла-последователя. Если последователь настроен как асинхронный, отказ никак не отразится на лидере. Если для последователя используется синхронная репликация, отказ приведёт к остановке транзакции на лидере, так как он перестанет получать подтверждение транзакций от последователя и транзакция не сможет завершиться. Подробное описание того, как настроить синхронную репликацию в BiHA-кластере, находится в Настройка кворумной синхронной и асинхронной репликации.
Сбой соединения между узлом-лидером и узлом-последователем. В этом случае лидер не может отправить, а последователь не может получить данные. Обратите внимание, что если пользователи подключены к лидеру, разрешать пишущие транзакции на последователе нельзя. Любые изменения, сделанные на последователях, нельзя будет восстановить на лидере. Чтобы избежать потери изменений, настраивайте сеть с резервными каналами. Лучше всего настроить свой канал передачи данных для каждого последователя, чтобы предупредить проблемы, связанные с единой точкой отказа.
В аварийной ситуации, например отказе операционной системы или оборудования, можно переустановить Postgres Pro и удалить расширение biha из shared_preload_libraries
, чтобы вернуться к работе в максимально короткие сроки.
27.1.1. Конфигурация Postgres Pro #
Для корректной работы BiHA устанавливает некоторые параметры конфигурации Postgres Pro и создаёт ряд вспомогательных объектов:
Утилита bihactl добавляет
biha
в переменную shared_preload_libraries в файле postgresql.conf и, если применимо, в файле postgresql.auto.conf:shared_preload_libraries = 'biha'
Этот параметр необходим для работы BiHA-кластера. Если в shared_preload_libraries уже имеются другие библиотеки,
biha
будет добавлена в конец списка.Утилита bihactl создаёт следующие файлы:
pg_hba.biha.conf
добавляется в файл pg_hba.conf с помощью директивы включения. Файлpg_hba.biha.conf
содержит правила аутентификации для роли biha_replication_user на узлах BiHA-кластера:host postgres biha_replication_user all scram-sha-256 host biha_db biha_replication_user all scram-sha-256 host replication biha_replication_user all scram-sha-256
Метод аутентификации по умолчанию — scram-sha-256. Однако, если параметр password_encryption уже был задан в файле postgresql.conf, BiHA будет использовать имеющееся значение.
postgresql.biha.conf
добавляется в файл postgresql.conf с помощью директивы включения.
Создаётся база данных
biha_db
, расширение biha и ряд ролей, специфичных для BiHA. За дополнительной информацией обратитесь к Роли.Создаются слоты репликации с именами формата
biha_node_
. Слоты управляются автоматически, изменять или удалять их вручную не нужно.id
В файле
postgresql.biha.conf
утилита bihactl устанавливает следующие параметры конфигурации Postgres Pro:hot_standby —
on
(значение по умолчанию). Этот параметр не рекомендуется изменять.wal_level —
replica
(значение по умолчанию). Если уже было задано значениеlogical
, BiHA будет использовать имеющееся значение. Этот параметр не рекомендуется изменять.max_wal_senders устанавливается с учётом числа процессов-передатчиков WAL, необходимых для корректной работы BiHA, которое зависит от кворума, заданного в параметре biha.nquorum. Если значение
nquorum
равно3
или меньше, значениеmax_wal_senders
будет равно10
. В иных случаях значение рассчитывается по следующей формуле:
. Имейте это в виду при изменении значения параметракворум_BiHA
* 2 + 3max_wal_senders
. За подробной информацией об уменьшении значенияmax_wal_senders
и некоторых других параметров конфигурации Postgres Pro обратитесь к Подразделу 27.1.1.1.max_replication_slots — значение равно
max_wal_senders + 1
. Минимальное значение —11
. Этот параметр не рекомендуется изменять. Учитывайте эту информацию при изменении значения параметраmax_replication_slots
.max_slot_wal_keep_size —
5GB
. Если значение уже было задано, BiHA будет использовать имеющееся значение. При необходимости значение можно изменить.В отличие от стандартной конфигурации ведущий-ведомый, BiHA-кластер хранит файлы WAL на всех узлах, чтобы отстающий узел мог нагнать остальные узлы. Для этого каждый узел использует слоты репликации, определяет самый отстающий узел и сохраняет столько файлов WAL, сколько может потребоваться для отстающего узла.
При настройке BiHA-кластера убедитесь, что вы выбрали оптимальное значение для этого параметра во избежание следующих проблем:
Если количество необходимых файлов WAL превышает значение max_slot_wal_keep_size, старые файлы WAL будут удалены. В результате отстающий узел не получит необходимые данные, изменит своё состояние на NODE_ERROR и остановит репликацию данных.
Если значение параметра max_slot_wal_keep_size равно
-1
(что означает, что файлы WAL никогда не удаляются) или превышает доступное дисковое пространство, это может привести к переполнению дискового хранилища.Если значение параметра max_slot_wal_keep_size слишком мало, заданного в нём пространства может оказаться недостаточно для хранения файлов WAL, необходимых, чтобы отстающий узел нагнал остальные узлы и продолжил работу.
wal_keep_size —
1GB
. Если значение уже было задано, BiHA будет использовать имеющееся значение. При необходимости этот параметр можно изменять.application_name задан в формате
biha_node_
. Этот параметр не рекомендуется изменять.идентификатор
listen_addresses —
*
. Этот параметр не рекомендуется изменять.порт — устанавливается порт Postgres Pro по умолчанию. Если порт по умолчанию был изменён, BiHA будет использовать имеющееся значение. Этот параметр не рекомендуется изменять.
primary_conninfo, primary_slot_name, synchronous_standby_names изменяются и управляются только через BiHA.
Когда расширение biha загружено и настроено, эти параметры нельзя изменить с помощью ALTER SYSTEM.
Эти параметры хранятся в файле
pg_biha/biha.conf
, а также в разделяемой памяти процесса biha. Когда эти параметры изменяются, biha отправляет сигналSIGHUP
, чтобы проинформировать другие процессы об изменениях. Если в это время изменить какие-либо другие параметры и не перечитать конфигурацию, изменённые параметры могут быть перечитаны неожиданно.Postgres Pro ведёт себя вышеописанным образом, только когда расширение biha загружено и настроено, т.е. когда библиотека указана в переменной
shared_preload_libraries
и установлены необходимые параметры biha.*. В других случаях Postgres Pro работает, как обычно.
Во время работы BiHA создаёт следующие служебные файлы в каталоге данных:
standby.signal — используется для запуска узлов в режиме резервного сервера. Файл необходим для того, чтобы сделать расширение biha доступным только для чтения при запуске Postgres Pro. Файл удаляется с лидера, когда лидер переходит в состояние
LEADER_RW
.biha.state
иbiha.conf
— файлы в каталогеpg_biha
, необходимые для сохранения внутреннего состояния и конфигурации расширения biha.
27.1.1.1. Уменьшение значений параметров Postgres Pro #
В BiHA-кластере успешно уменьшить значения некоторых параметров конфигурации Postgres Pro возможно только с помощью приведённой ниже инструкции.
Используйте эту инструкцию для уменьшения значений следующих параметров:
Предупреждение
Изменяйте эти параметры конфигурации с осторожностью и убедитесь, что они имеют одинаковые значения на всех узлах BiHA-кластера. В противном случае изменение лидера может привести к непредвиденному поведению кластера.
Уменьшить значения вышеупомянутых параметров конфигурации кластера можно следующим образом:
На лидере уменьшите значение необходимого параметра конфигурации.
(Необязательно) Чтобы избежать выборов, увеличьте значение параметра biha.nquorum до общего числа узлов в кластере с помощью функции biha.set_nquorum.
Остановите и запустите узел-лидер с помощью pg_ctl.
Во время запуска лидер проверяет, что другие узлы работоспособны и продолжают считать его лидером. Если все узлы работают корректно, лидер применяет изменённые значения и успешно запускается. В противном случае лидер завершает работу и выводит в журнал соответствующее сообщение.
Убедитесь, что все узлы получили информацию об изменении параметра конфигурации на лидере.
Для этого можно использовать утилиту pg_controldata или выдержать паузу после перезапуска лидера, чтобы у других узлов было достаточно времени для получения обновлений.
На других узлах уменьшите значение параметра конфигурации таким же образом, как и на лидере.
Остановите и запустите узлы с помощью pg_ctl.
27.1.2. Варианты конфигурации кластера #
Существует несколько вариантов конфигурации кластера.
Три и более узлов, один из которых является лидером, а остальные — последователями.
Ниже представлены возможные сценарии при отказе лидера или сбое сетевого подключения:
При отказе текущего лидера новый лидер избирается автоматически. Чтобы стать лидером, последователь должен получить максимальное количество голосов. Количество голосов должно быть больше или равно значению, заданному в параметре biha.nquorum.
При сбоях сетевого соединения внутри кластера BiHA кластер может разделиться на несколько групп узлов. В этом случае новый лидер избирается во всех группах, в которых количество узлов больше или равно значению biha.nquorum. После восстановления соединения лидер кластера выбирается между старым и новоизбранным лидером в зависимости от значения
term
. Узел с наибольшим значениемterm
становится новым лидером. Рекомендуется установить значение biha.minnodes равным значению biha.nquorum.
Кластер из двух узлов, состоящий из лидера и последователя.
Примечание
Не рекомендуется использовать кластер из двух узлов, поскольку такая конфигурация может вызвать проблемы разделения кластера. Чтобы их избежать, добавьте узел-рефери.
Ниже представлены возможные сценарии при отказе лидера или сбоях сети:
При отказе лидера узел-последователь автоматически становится новым лидером, если для параметра конфигурации biha.nquorum установлено значение
1
.Если между лидером и последователем происходят сетевые сбои, и для обоих параметров конфигурации biha.nquorum и biha.minnodes установлено значение
1
, кластер может разделиться на двух лидеров, доступных для чтения и записи. Подобных проблем позволяет избежать узел-рефери.
Конфигурация с одним узлом-лидером. Этот вариант возможно использовать, пока не будут настроены последователи. Логично, что узел нельзя заменить при сбое ввиду отсутствия последователей, которые могут стать лидером.
Кластер с тремя узлами, состоящий из лидера, последователя и рефери. Узел-рефери используется для голосования при выборе нового лидера, но сам не может стать лидером. При возникновении сбоев кластер с рефери ведёт себя как кластер с тремя узлами (лидером и двумя последователями). Чтобы подробнее узнать о рефери, обратитесь к Узел-рефери в BiHA-кластере.
Примечание
Вы можете вручную назначить лидера с помощью функции biha.set_leader.
Рекомендуется установить для параметра biha.nquorum значение, большее или равное половине числа узлов в кластере.
При добавлении или удалении узлов из кластера всегда проверяйте значение biha.nquorum, учитывая наибольшее количество узлов, но не меньше, чем установлено в
nquorum
.
27.1.3. Выборы #
Выборы — это процесс определения лидера, который проводят последователи при отказе текущего лидера. В результате выборов лидером кластера становится последователь с наибольшим числом записей в WAL. Чтобы узел мог быть избран лидером, для параметров biha.can_be_leader и biha.can_vote этого узла должно быть установлено значение true
.
Выборы проводятся с учётом кворума кластера, то есть минимального количества узлов, участвующих в голосовании. Значение кворума задаётся в параметре biha.nquorum при инициализации кластера командой bihactl
init. Узлы, для которых в параметре biha.can_vote установлено значение false
, исключаются из голосования и игнорируются в nquorum
. Узлы в состоянии NODE_ERROR
не могут голосовать.
Чтобы начались выборы, последователи должны не получить максимальное количество сообщений о контроле состояния, заданное функцией biha.set_heartbeat_max_lost. На этом этапе один из последователей выдвигает себя в качестве кандидата в лидеры (CANDIDATE
), и начинаются выборы. Если в этом случае лидер не получает заданное количество сообщений о контроле состояния от последователя, состояние последователя меняется на UNKNOWN
для лидера. В синхронном кластере можно задать приоритет узлов с помощью параметра biha.node_priority. Если в кластере только два узла и вы хотите избежать возможных проблем разделения кластера во время выборов, создайте узел-рефери, который участвует в голосовании так же, как последователи. За подробностями обратитесь к Узел-рефери в BiHA-кластере.
Например, в случае отказа одного узла-последователя в кластере из трёх узлов, где значение
, узел-лидер продолжит работать. При отказе лидера в таком кластере два оставшихся последователя начнут выборы. После избрания нового лидера значение поколения кластера term увеличивается на единицу для всех узлов, то есть для нового лидера и оставшихся последователей nquorum
=2
, а для старого лидера останется равным term
=2
. Когда старый лидер возвращается в кластер, происходит его понижение, то есть старый лидер становится последователем.term
=1
После избрания нового лидера последователи начинают получать файлы WAL уже от него. Обратите внимание, что при выборе нового лидера старый лидер понижается и становится недоступным для пишущих транзакций, чтобы избежать проблем разделения кластера (split brain). Вы можете вручную повысить старого лидера, используя функцию biha.set_leader. Механизмы кворума и поколения реализованы в BiHA на базе алгоритма консенсуса Raft.
27.1.4. Узел-рефери в BiHA-кластере #
В отказоустойчивом кластере можно создать узел-рефери, который участвует в выборах и помогает избежать потенциальной проблемы разделения кластера (split brain), состоящего только из лидера и последователя. В этом случае после создания рефери установите значение 2
для обоих параметров конфигурации biha.nquorum и biha.minnodes.
По умолчанию на рефери отсутствует база данных postgres
и пользовательские данные. За подробной информацией обратитесь к разделу База данных postgres на рефери.
Примечание
Для рефери требуется намного меньше дискового пространства, ресурсов процессора и памяти, чем для обычных узлов. Но так как рефери создаётся через частичное копирование лидера, он наследует и параметры конфигурации лидера. Чтобы избежать избыточного потребления ресурсов, перед первым запуском рефери убедитесь, что его параметры конфигурации соответствуют реальным аппаратным ресурсам сервера, на котором запущен рефери. Например, установите для параметра shared_buffers значение по умолчанию 128 МБ.
Расширение biha поддерживает следующие режимы работы рефери:
Режим
referee
. В этом режиме узел принимает участие только в выборах лидера, но не в репликации данных. Кроме того, для рефери не создаются слоты репликации ни на лидере, ни на последователях.Режим
referee_with_wal
. В этом режиме узел участвует не только в выборах лидера таким же образом, как и в режимеreferee
, но и в репликации данных, и получает весь WAL с узла-лидера. Если на момент начала выборов больше всего записей WAL среди узлов кластера накопится на узле-рефери, то есть у рефери будет наибольший LSN, узел-последователь будет пытаться получить недостающие файлы WAL с рефери. Этот процесс важен для того, чтобы узел-рефери не перешел в состояниеNODE_ERROR
, что возможно при расхождении WAL. Дляreferee_with_wal
,apply lag
равенNULL
иapply ptr
невозможно изменить, так как рефери не применяет данные пользователя.
Вне зависимости от установленного режима работы узла-рефери, он отправляет и получает сообщения о контроле состояния по каналу управления, в том числе с использованием SSL, участвует в выборах так же, как и узлы-последователи, поддерживает функции мониторинга кластера и должен учитываться, когда задаётся значение параметра biha.minnodes. Обратите внимание, что рефери — это конечное состояние узла: его нельзя сделать лидером при помощи функции biha.set_leader, и он не может стать узлом-последователем. Если по какой-либо причине последователь «не видит» лидера, но его видит рефери, рефери не позволит последователю стать лидером. Если лидер с более высоким значением поколения term
подключится к рефери, рефери понизит статус лидера с более низким значением term
до последователя.
27.1.4.1. База данных postgres
на рефери #
При добавлении рефери, утилита pg_basebackup создаёт частичную резервную копию лидера. Это значит, что, по умолчанию, на рефери с лидера копируются только база данных biha_db
и системные таблицы. База данных postgres
и пользовательские данные не копируются. Это сделано намеренно для уменьшения потребления ресурсов.
Однако некоторые утилиты и системы мониторинга используют базу данных postgres
для подключения к узлам. Если необходимо, чтобы база данных postgres
присутствовала на рефери, вы можете указать параметр --referee-with-postgres-db при добавлении узла в режиме referee
или referee_with_wal
. Этот параметр копирует на рефери базу данных postgres
со всеми объектами. Для рефери в режиме referee_with_wal
также применяются записи WAL, относящиеся к базе данных postgres
. Это значит, что все новые объекты, созданные в базе данных postgres
, будут также созданы на рефери в режиме referee_with_wal
.
Примечание
Обратите внимание, что вышесказанное относится к базе данных postgres
, создаваемой при инициализации экземпляра. Если удалить базу данных postgres
на лидере, она также будет удалена и на рефери без возможности восстановления.