В случае, если демон поиска Manticore останавливается и в кластере не остается узлов для обслуживания запросов, необходимо восстановление. Благодаря мульти-мастерной природе библиотеки Galera, используемой для репликации, кластер репликации Manticore является единой логической сущностью, которая поддерживает согласованность своих узлов и данных, а также состояние всего кластера. Это позволяет безопасно выполнять записи на нескольких узлах одновременно и обеспечивает целостность кластера.
Однако это также создает определенные сложности. Рассмотрим несколько сценариев, используя кластер из узлов A, B и C, чтобы понять, что нужно делать, когда некоторые или все узлы становятся недоступными.
Когда узел A останавливается, другие узлы получают сообщение о "нормальном завершении работы". Размер кластера уменьшается, и происходит перерасчет кворума.
При запуске узел A присоединяется к кластеру и не будет обслуживать транзакции записи, пока полностью не синхронизируется с кластером. Если кэш writeset на донорских узлах B или C (который можно контролировать с помощью параметра Galera кластера gcache.size) все еще содержит все транзакции, пропущенные узлом A, узел A получит быстрый инкрементальный перенос состояния (IST), то есть перенос только пропущенных транзакций. Если нет, произойдет перенос состояния снимка (SST), который включает передачу файлов таблиц.
В сценарии, когда узлы A и B остановлены, размер кластера уменьшается до одного, и узел C формирует основной компонент для обработки транзакций записи.
Узлы A и B затем могут быть запущены как обычно и присоединятся к кластеру после запуска. Узел C выступает в роли донора, предоставляя перенос состояния узлам A и B.
Все узлы остановлены как обычно, и кластер выключен.
Проблема теперь в том, как инициализировать кластер. Важно, чтобы при корректном завершении работы searchd узлы записывали номер последней выполненной транзакции в файл grastate.dat в каталоге кластера вместе с флагом safe_to_bootstrap. Узел, который был остановлен последним, будет иметь опцию safe_to_bootstrap: 1 и самый продвинутый номер seqno.
Важно, чтобы этот узел запускался первым для формирования кластера. Для инициализации кластера сервер должен быть запущен на этом узле с флагом --new-cluster. В Linux также можно запустить manticore_new_cluster, который запустит Manticore в режиме --new-cluster через systemd.
Если другой узел запускается первым и инициализирует кластер, тогда самый продвинутый узел присоединится к этому кластеру, выполнит полный SST и получит файл таблицы, в котором некоторые транзакции отсутствуют по сравнению с файлами таблиц, которые он имел ранее. Поэтому важно запускать первым узел, который был остановлен последним, он должен иметь флаг safe_to_bootstrap: 1 в grastate.dat.
В случае сбоя или сетевой ошибки, из-за которой узел A исчезает из кластера, узлы B и C попытаются переподключиться к узлу A. При неудаче они удалят узел A из кластера. При этом два из трех узлов продолжают работать, кластер сохраняет кворум и функционирует нормально.
При перезапуске узел A автоматически присоединится к кластеру, как описано в Случае 1.
Узлы A и B вышли из строя. Узел C не может сформировать кворум самостоятельно, так как 1 узел меньше половины от общего числа узлов (3). В результате кластер на узле C переходит в состояние non-primary и отклоняет любые транзакции записи с сообщением об ошибке.
Тем временем узел C ждет подключения других узлов и также пытается к ним подключиться. Если это происходит, и сеть восстанавливается, а узлы A и B возвращаются в онлайн, кластер автоматически восстанавливается. Если узлы A и B просто временно отключены от узла C, но могут общаться друг с другом, они продолжат работать нормально, так как все еще формируют кворум.
Однако, если оба узла A и B вышли из строя или перезапустились из-за отключения питания, кто-то должен активировать основной компонент на узле C с помощью следующей команды:
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1Важно отметить, что перед выполнением этой команды необходимо убедиться, что другие узлы действительно недоступны. В противном случае может возникнуть ситуация "split-brain" и сформируются отдельные кластеры.
Все узлы вышли из строя. В этой ситуации файл grastate.dat в каталоге кластера не был обновлен и не содержит действительного номера последовательности seqno.
Если это произошло, необходимо найти узел с самыми свежими данными и запустить сервер на нем с использованием ключа командной строки --new-cluster-force. Все остальные узлы запустятся как обычно, как описано в Случае 3).
В Linux также можно использовать команду manticore_new_cluster --force, которая запустит Manticore в режиме --new-cluster-force через systemd.
Split-brain может привести к переходу кластера в состояние неосновного узла. Например, рассмотрим кластер, состоящий из четного числа узлов (четыре), таких как две пары узлов, расположенных в разных дата-центрах. Если сетевая ошибка прерывает соединение между дата-центрами, возникает split-brain, так как каждая группа узлов удерживает ровно половину кворума. В результате обе группы прекращают обработку транзакций записи, поскольку модель репликации Galera отдает приоритет согласованности данных, и кластер не может принимать транзакции записи без кворума. Однако узлы в обеих группах пытаются переподключиться к узлам из другой группы в попытке восстановить кластер.
Если кто-то хочет восстановить кластер до восстановления сети, следует выполнить те же шаги, описанные в Case 5, но только для одной группы узлов.
После выполнения оператора группа с узлом, на котором он был выполнен, сможет снова обрабатывать транзакции записи.
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1Однако важно отметить, что если оператор будет выполнен в обеих группах, это приведет к формированию двух отдельных кластеров, и последующее восстановление сети не приведет к повторному объединению групп.