Благодаря встроенным возможностям отказоустойчивости Postgres Pro позволяет создать кластер с одним узлом-лидером и нескольмими узлами-последователями. Лидер является ведущим сервером BiHA-кластера, а последователи — репликами лидера.
Утилита bihactl позволяет инициализировать кластер и создавать узел-лидер, добавлять узлы-последователи, преобразовывать существующий узел в узел-лидер или узел-последователь в BiHA-кластере, а также проверять статус узлов кластера. Лидер доступен для чтения и записи, в то время как последователи доступны только для чтения и реплицируют данные с лидера в синхронном или асинхронном режиме.
Физическая потоковая репликация, реализованная в BiHA , обеспечивает отказоустойчивость, защищая от отказов серверов и системы хранения данных. При физической репликации файлы WAL узла-лидера синхронно или асинхронно отправляются на узел-последователь и применяются на нём. При синхронной репликации для каждой фиксации транзакции пользователь ожидает подтверждения от узла-последователя. Узел-последователь BiHA-кластера может использоваться для выполнения следующих задач:
Выполнение читающих транзакций в базе данных.
Подготовка отчётов.
Создание таблиц в оперативной памяти для пишущих транзакций.
Подготовка резервной копии узла-последователя.
Восстановление повреждённых блоков данных на узле-лидере путём получения этих блоков с узла-последователя.
Проверка повреждённых записей в файлах WAL.
Физическая потоковая репликация, реализованная в BiHA, обеспечивает защиту от следующих видов отказов:
Отказ узла-лидера. В этом случае статус узла-последователя повышается, и он становится новым лидером кластера. Повышение выполняется либо вручную с помощью функции biha.set_leader, либо автоматически с помощью выборов.
Отказ узла-последователя. Если последователь настроен как асинхронный, отказ никак не отразится на лидере. Если для последователя используется синхронная репликация, отказ приведёт к остановке транзакции на лидере, так как он перестанет получать подтверждение транзакций от последователя и транзакция не сможет завершиться. Подробное описание того, как настроить синхронную репликацию в BiHA-кластере, находится в Подразделе 27.3.8.
Сбой соединения между узлом-лидером и узлом-последователем. В этом случае лидер не может отправить, а последователь не может получить данные. Обратите внимание, что если пользователи подключены к лидеру, разрешать пишущие транзакции на последователе нельзя. Любые изменения, сделанные на последователях, нельзя будет восстановить на лидере. Чтобы избежать потери изменений, настраивайте сеть с резервными каналами. Лучше всего настроить свой канал передачи данных для каждого последователя, чтобы предупредить проблемы, связанные с единой точкой отказа.
В аварийной ситуации, например отказе операционной системы или оборудования, можно переустановить Postgres Pro и удалить расширение biha из shared_preload_libraries, чтобы вернуться к работе в максимально короткие сроки.
Для корректной работы 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 — значение зависит от кворума, заданного в параметре biha.nquorum. Если значение nquorum равно 3 или меньше, значение max_wal_senders будет равно 10. В иных случаях значение рассчитывается по следующей формуле: . Этот параметр не рекомендуется изменять.кворум_BiHA * 2 + 3
max_replication_slots — значение равно max_wal_senders + 1. Минимальное значение — 11. Этот параметр не рекомендуется изменять.
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.
Существует несколько вариантов конфигурации кластера.
Три и более узлов, один из которых является лидером, а остальные — последователями.
Ниже представлены возможные сценарии при отказе лидера или сбое сетевого подключения:
При отказе текущего лидера новый лидер избирается автоматически. Чтобы стать лидером, последователь должен получить максимальное количество голосов. Количество голосов должно быть больше или равно значению, заданному в параметре biha.nquorum.
При сбоях сетевого соединения внутри кластера BiHA кластер может разделиться на несколько групп узлов. В этом случае новый лидер избирается во всех группах, в которых количество узлов больше или равно значению biha.nquorum. После восстановления соединения лидер кластера выбирается между старым и новоизбранным лидером в зависимости от значения term. Узел с наибольшим значением term становится новым лидером. Рекомендуется установить значение biha.minnodes равным значению biha.nquorum.
Кластер из двух узлов, состоящий из лидера и последователя.
Не рекомендуется использовать кластер из двух узлов, поскольку такая конфигурация может вызвать проблемы разделения кластера. Чтобы их избежать, добавьте узел-рефери.
Ниже представлены возможные сценарии при отказе лидера или сбоях сети:
При отказе лидера узел-последователь автоматически становится новым лидером, если для параметра конфигурации biha.nquorum установлено значение 1.
Если между лидером и последователем происходят сетевые сбои, и для обоих параметров конфигурации biha.nquorum и biha.minnodes установлено значение 1, кластер может разделиться на двух лидеров, доступных для чтения и записи. Подобных проблем позволяет избежать узел-рефери.
Конфигурация с одним узлом-лидером. Этот вариант возможно использовать, пока не будут настроены последователи. Логично, что узел нельзя заменить при сбое ввиду отсутствия последователей, которые могут стать лидером.
Кластер с тремя узлами, состоящий из лидера, последователя и рефери. Узел-рефери используется для голосования при выборе нового лидера, но сам не может стать лидером. При возникновении сбоев кластер с рефери ведёт себя как кластер с тремя узлами (лидером и двумя последователями). Чтобы подробнее узнать о рефери, обратитесь к Подразделу 27.1.4.
Вы можете вручную назначить лидера с помощью функции biha.set_leader.
Рекомендуется установить для параметра biha.nquorum значение, большее или равное половине числа узлов в кластере.
При добавлении или удалении узлов из кластера всегда проверяйте значение biha.nquorum, учитывая наибольшее количество узлов, но не меньше, чем установлено в nquorum.
Выборы — это процесс определения лидера, который проводят последователи при отказе текущего лидера. В результате выборов лидером кластера становится последователь с наибольшим числом записей в WAL. Чтобы узел мог быть избран лидером, для параметров biha.can_be_leader и biha.can_vote этого узла должно быть установлено значение true.
Выборы проводятся с учётом кворума кластера, то есть минимального количества узлов, участвующих в голосовании. Значение кворума задаётся в параметре biha.nquorum при инициализации кластера командой bihactl init. Узлы, для которых в параметре biha.can_vote установлено значение false, исключаются из голосования и игнорируются в nquorum.
Чтобы начались выборы, последователи должны не получить максимальное количество сообщений о контроле состояния, заданное функцией biha.set_heartbeat_max_lost. На этом этапе один из последователей выдвигает себя в качестве кандидата в лидеры (CANDIDATE), и начинаются выборы. Если в этом случае лидер не получает заданное количество сообщений о контроле состояния от последователя, состояние последователя меняется на UNKNOWN для лидера. В синхронном кластере можно задать приоритет узлов с помощью параметра biha.node_priority. Если в кластере только два узла и вы хотите избежать возможных проблем разделения кластера во время выборов, создайте узел-рефери, который участвует в голосовании так же, как последователи. За подробностями обратитесь к Подразделу 27.1.4.
Например, в случае отказа одного узла-последователя в кластере из трёх узлов, где значение , узел-лидер продолжит работать. При отказе лидера в таком кластере два оставшихся последователя начнут выборы. После избрания нового лидера значение поколения кластера term увеличивается на единицу для всех узлов, то есть для нового лидера и оставшихся последователей nquorum=2, а для старого лидера останется равным term=2. Когда старый лидер возвращается в кластер, происходит его понижение, то есть старый лидер становится последователем.term=1
После избрания нового лидера последователи начинают получать файлы WAL уже от него. Обратите внимание, что при выборе нового лидера старый лидер понижается и становится недоступным для пишущих транзакций, чтобы избежать проблем разделения кластера (split brain). Вы можете вручную повысить старого лидера, используя функцию biha.set_leader. Механизмы кворума и поколения реализованы в BiHA на базе алгоритма консенсуса Raft.
В отказоустойчивом кластере можно создать узел-рефери, который участвует в выборах узла-лидера и помогает избежать потенциальной проблемы разделения кластера (split brain), состоящего только из лидера и последователя. В этом случае после создания рефери установите значение 2 для обоих параметров конфигурации biha.nquorum и biha.minnodes.
При создании рефери на него копируются только база данных biha_db и системные таблицы. База данных postgres и пользовательские данные не копируются.
Расширение 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 до последователя.