Если репликационный узел или весь кластер становится недоступным, правильная процедура восстановления зависит от того, сколько узлов остаются доступными и был ли останов чистым или внезапным.
Репликационный кластер следует рассматривать как одну логическую систему, а не набор независимых серверов. Это обеспечивает многомастерные записи и согласованность данных, но также означает, что вы должны осторожно восстанавливать кворум. В частности, не запускайте команду ручного восстановления, которая восстанавливает записи на сохранившейся стороне, пока не убедитесь, что пропавшие узлы действительно отсутствуют. Эта команда показана далее на этой странице как SET CLUSTER <name> GLOBAL 'pc.bootstrap' = 1. Если запустить её слишком рано, можно создать расщепление мозга и получить два независимых кластера.
Для примеров ниже предполагается кластер с узлами A, B и C, если не указано иначе.
Сначала определите, в какой ситуации вы находитесь:
- Есть хотя бы один узел онлайн?
- Узел был остановлен чисто или он упал? Чистая остановка означает, что
searchdбыл остановлен нормально и имел время сохранить состояние репликации перед выходом. Падение, потеря питания илиkill -9не являются чистой остановкой. - Сохранившаяся часть кластера ещё имеет кворум? Кворум означает, что достаточно узлов могут видеть друг друга, чтобы безопасно оставаться кластером с возможностью записи.
- Если все узлы отключены, какой узел следует запустить первым для восстановления кластера?
Полезные проверки:
SHOW STATUS LIKE 'cluster_<name>_status'SHOW STATUS LIKE 'cluster_<name>_size'SHOW STATUS LIKE 'cluster_<name>_node_state'- если все узлы отключены, проверьте
grastate.dat, небольшой файл состояния репликации, хранящийся в директории данных кластера. Особенно обратите внимание наseqnoиsafe_to_bootstrap: при чистой остановке лучший узел для запуска первым обычно тот, с наиболее продвинутымseqnoиsafe_to_bootstrap: 1. Для полной процедуры bootstrap см. Перезапуск кластера.
Пример того, как grastate.dat может выглядеть после чистой остановки:
# saved replication state
version: 2.1
uuid: <cluster-uuid>
seqno: 12345
safe_to_bootstrap: 1
В этом примере:
seqno: 12345означает, что этот узел знает о транзакциях до порядкового номер 12345safe_to_bootstrap: 1означает, что этот узел помечен как безопасный для запуска первым
При чистом восстановлении после остановки всех узлов, это обычно тот тип узла, который вы запускаете первым с --new-cluster для восстановления кластера.
После восстановления, дождитесь, пока перезапущенный узел сообщает cluster_<name>_status=primary и cluster_<name>_node_state=synced, прежде чем считать его полностью доступным для записи. Это можно проверить с помощью SHOW STATUS LIKE 'cluster_<name>_status' и SHOW STATUS LIKE 'cluster_<name>_node_state'. В локальных тестах перезапущенные узлы иногда некоторое время находились в состоянии cluster_<name>_node_state=joining и cluster_<name>_status=disconnected перед достижением synced/primary.
Если узел A остановлен нормально, узлы B и C продолжают обслуживать записи. Вы можете подтвердить, что кластер всё ещё здоров на этих узлах с помощью SHOW STATUS LIKE 'cluster_<name>_status' и SHOW STATUS LIKE 'cluster_<name>_size'.
Когда узел A запускается снова, он автоматически присоединяется к кластеру. До завершения синхронизации не отправляйте записи на этот узел. Проверьте SHOW STATUS LIKE 'cluster_<name>_status' и SHOW STATUS LIKE 'cluster_<name>_node_state' и дождитесь primary / synced.
Если узлы-доноры B или C ещё имеют все транзакции, которые узел A пропустил, в своём репликационном кэше, узел A может догнать их с помощью инкрементного переноса состояния (IST). IST означает инкрементный перенос состояния. Это означает, что узел получает только транзакции, которые он пропустил, поэтому восстановление обычно быстрее и легче. В противном случае потребуется перенос состояния через снимок (SST). SST означает перенос состояния через снимок. Это означает копирование файлов таблиц из другого узла вместо простого воспроизведения пропущенных транзакций. SST более тяжелый: обычно он медленнее, перемещает больше данных и может сделать восстановление более разрушительным на больших кластерах.
Если узлы A и B остановлены чисто и узел C остаётся онлайн, узел C может продолжать принимать записи. Проверьте SHOW STATUS LIKE 'cluster_<name>_status' и SHOW STATUS LIKE 'cluster_<name>_size' на узле C, если хотите подтвердить, что он теперь единственный активный узел.
Когда узлы A и B запускаются снова, они автоматически присоединяются и синхронизируются с узлом C. Во время присоединения проверьте SHOW STATUS LIKE 'cluster_<name>_status', SHOW STATUS LIKE 'cluster_<name>_node_state', и SHOW STATUS LIKE 'cluster_<name>_size'. Дождитесь, пока все узлы показывают primary / synced и ожидаемый размер кластера, прежде чем считать восстановление завершенным.
Если все узлы были остановлены нормально, кластер полностью отключен и должен быть запущен снова специальным образом, чтобы он мог стать первым работающим узлом кластера.
При чистой остановке каждый узел записывает свой последний номер транзакции в grastate.dat. Узел, который был остановлен последним, является самым безопасным узлом для запуска первым:
- он имеет наиболее продвинутый
seqno - он имеет
safe_to_bootstrap: 1
Запустите этот узел с --new-cluster. Это указывает Manticore запустить новую копию кластера с этого узла. Если вы запускаете Manticore через systemd в Linux, используйте manticore_new_cluster. Он запускает Manticore в режиме --new-cluster за вас.
После этого запустите остальные узлы нормально и позвольте им присоединиться. Проверьте восстановление с помощью SHOW STATUS LIKE 'cluster_<name>_status', SHOW STATUS LIKE 'cluster_<name>_node_state', и SHOW STATUS LIKE 'cluster_<name>_size'.
Если вы запустите менее продвинутый узел первым, более продвинутый узел позже присоединится к нему и получит полный SST из более старого состояния, что может отбросить транзакции, которые существовали только на более продвинутом узле. Поэтому узел с safe_to_bootstrap: 1 должен быть вашим первым выбором.
Если узел A исчезает из-за сбоя или сетевой проблемы, узлы B и C сначала попытаются переподключиться к нему. Если это не удается, они удаляют его из кластера, пересчитывают кворум и продолжают работать как основной кластер.
В локальных тестах это удаление узла не было мгновенным: оставшиеся узлы сохраняли старый размер кластера в течение нескольких секунд, прежде чем отбросить отказавший узел и переключиться на меньший основной кластер.
Когда узел A снова запускается, он автоматически присоединяется и наверстывает упущенное так же, как после чистого завершения работы одного узла. Снова используйте SHOW STATUS LIKE 'cluster_<name>_status', SHOW STATUS LIKE 'cluster_<name>_node_state' и SHOW STATUS LIKE 'cluster_<name>_size', чтобы подтвердить завершение восстановления.
Если узлы A и B потеряны, и работает только узел C, узел C больше не имеет кворума в трехузловом кластере. Он переключается в состояние non-primary и отклоняет запись.
Ошибка записи явная:
ERROR 1064 (42000): cluster '<name>' is not ready, not primary state (synced)
Если узлы A и B только временно отключены, но все еще могут видеть друг друга, они могут продолжать принимать записи, в то время как узел C остается изолированным. Используйте SHOW STATUS LIKE 'cluster_<name>_status' на каждой стороне, если вам нужно увидеть, какая сторона все еще доступна для записи.
Если узлы A и B действительно аварийно завершили работу, а узел C — единственная сохранившаяся копия, с которой вы хотите продолжать работать, выполните эту команду на узле C, чтобы снова сделать его доступным для записи:
Если вы подтвердили, что другие узлы действительно отключены, выполните:
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1Важно:
- выполняйте это только после того, как убедитесь, что другие узлы недостижимы
- выполняйте это только на стороне, которая должна выжить
- после начальной загрузки узел снова может принимать записи, и другие узлы позже смогут к нему повторно присоединиться
Если каждый узел аварийно завершил работу, grastate.dat, как правило, больше не заслуживает доверия для обычного выбора начальной загрузки. В локальных тестах все узлы показывали:
seqno: -1safe_to_bootstrap: 0
В этой ситуации выберите узел с самыми свежими данными и запустите его с --new-cluster-force. Это заставляет Manticore запустить новую копию кластера с этого узла, даже несмотря на то, что обычные метаданные чистого завершения работы не заслуживают доверия. Если вы запускаете Manticore через systemd в Linux, используйте manticore_new_cluster --force. Он запускает Manticore в режиме --new-cluster-force для вас.
Затем запустите оставшиеся узлы в обычном режиме и позвольте им повторно присоединиться. Проверьте восстановление с помощью SHOW STATUS LIKE 'cluster_<name>_status', SHOW STATUS LIKE 'cluster_<name>_node_state' и SHOW STATUS LIKE 'cluster_<name>_size'.
Риск разделения мозга наиболее высок в кластерах с четным числом узлов. Например, представьте четыре узла, разделенных на две изолированные пары в двух центрах обработки данных. Каждая сторона имеет ровно половину от исходного числа участников, поэтому ни одна из сторон не имеет кворума, и обе стороны прекращают принимать записи.
Если вам необходимо восстановить запись до устранения проблемы с подключением, выберите только одну сторону разделения и выполните ту же команду восстановления там, чтобы эта сторона снова стала доступной для записи. Перед этим проверьте SHOW STATUS LIKE 'cluster_<name>_status' на обеих сторонах, чтобы знать, какая сторона в настоящее время является неосновной.
Выберите сторону, которая должна остаться доступным для записи кластером, затем выполните:
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1Никогда не выполняйте этот оператор на обеих сторонах. Если вы это сделаете, вы создадите два отдельных основных кластера, и они не объединятся автоматически при восстановлении сети.
В локальном тестировании внезапная потеря половины четырехузлового кластера воспроизвела то же поведение non-primary, и та же команда восстановления вернула одну выжившую половину в состояние primary.