Оператор ALTER CLUSTER <cluster_name> UPDATE nodes обновляет списки узлов на каждом узле в указанном кластере, чтобы включить все активные узлы кластера. Для получения дополнительной информации о списках узлов см. Присоединение к кластеру.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
ALTER CLUSTER posts UPDATE nodesPOST /cli -d "
ALTER CLUSTER posts UPDATE nodes
"$params = [
'cluster' => 'posts',
'body' => [
'operation' => 'update',
]
];
$response = $client->cluster()->alter($params);utilsApi.sql('ALTER CLUSTER posts UPDATE nodes')await utilsApi.sql('ALTER CLUSTER posts UPDATE nodes')res = await utilsApi.sql('ALTER CLUSTER posts UPDATE nodes');utilsApi.sql("ALTER CLUSTER posts UPDATE nodes");utilsApi.Sql("ALTER CLUSTER posts UPDATE nodes");utils_api.sql("ALTER CLUSTER posts UPDATE nodes", Some(true)).await;{u'error': u'', u'total': 0, u'warning': u''}{u'error': u'', u'total': 0, u'warning': u''}{"total":0,"error":"","warning":""}Если включены аутентификация и авторизация, команды ALTER CLUSTER ... UPDATE nodes, ALTER CLUSTER ... ADD и ALTER CLUSTER ... DROP используют сохраненного пользователя кластера. Чтобы изменить сохраненного пользователя кластера, выдайте новому пользователю право replication и выполните:
ALTER CLUSTER posts UPDATE user 'repl_user'
Новый сохраненный пользователь должен быть подготовлен с совпадающими данными аутентификации на узлах, которые будут участвовать в последующих операциях кластера. Эти операции завершатся сбоем, если сохраненный пользователь отсутствует, имеет другие данные аутентификации или лишится права replication.
Например, при первоначальном создании кластера список узлов, используемых для повторного присоединения к кластеру, был 10.10.0.1:9312,10.10.1.1:9312. С тех пор к кластеру присоединились другие узлы, и теперь активными узлами являются 10.10.0.1:9312,10.10.1.1:9312,10.15.0.1:9312,10.15.0.3:9312. Однако список узлов, используемых для повторного присоединения к кластеру, не был обновлен.
Чтобы исправить это, можно выполнить оператор ALTER CLUSTER ... UPDATE nodes, чтобы скопировать список активных узлов в список узлов, используемых для повторного присоединения к кластеру. После этого список узлов, используемых для повторного присоединения к кластеру, будет включать все активные узлы кластера.
Оба списка узлов можно просмотреть с помощью оператора Статус кластера (cluster_post_nodes_set и cluster_post_nodes_view).
Чтобы удалить узел из кластера репликации, выполните следующие шаги:
- Остановите узел
- Удалите информацию о кластере из файла
<data_dir>/manticore.json(обычно/var/lib/manticore/manticore.json) на остановленном узле. - Выполните
ALTER CLUSTER cluster_name UPDATE nodesна любом другом узле.
После этих шагов другие узлы забудут об отсоединенном узле, а отсоединенный узел забудет о кластере. Это действие не повлияет на таблицы в кластере или на отсоединенном узле.
EXIT CLUSTER <cluster_name> — это онлайн-эквивалент описанного выше ручного процесса отсоединения. Он удаляет локальный узел из кластера репликации, сохраняет локальные таблицы нетронутыми в качестве обычных локальных таблиц, сохраняет локальную конфигурацию, а затем просит оставшиеся узлы обновить свои сохраненные списки узлов с помощью существующего механизма ALTER CLUSTER ... UPDATE nodes.
EXIT CLUSTER posts
Используйте EXIT CLUSTER, когда хотите отсоединить только текущий узел. Используйте DELETE CLUSTER, когда хотите удалить кластер со всех узлов.
EXIT CLUSTER разрешен только для работоспособного локального узла в первичном кластере. Если команда возвращает предупреждение, локальное отсоединение уже выполнено, но может потребоваться дополнительное завершение. В этом случае выполните ALTER CLUSTER <cluster_name> UPDATE nodes на любом оставшемся узле, чтобы завершить обновление оставшихся метаданных кластера.
Если после EXIT CLUSTER оставшаяся сторона превращается в чистый кластер из одного узла, она остаётся кластером репликации. После корректного завершения работы этот оставшийся узел можно запускать обычным образом, и он должен вернуться в состояние primary / synced; в этом случае для самого себя --new-cluster не нужен.
Вы можете просмотреть информацию о статусе кластера, проверив статус узла. Это можно сделать с помощью команды Node status, которая отображает различную информацию об узле, включая переменные статуса кластера.
Формат вывода для переменных статуса кластера следующий: cluster_name_variable_name variable_value. Большинство переменных описаны в Galera Documentation Status Variables. В дополнение к этим переменным, Manticore Search также отображает:
cluster_name- имя кластера, определённое в настройке репликацииnode_state- текущий статус узла:closed,destroyed,joining,donor,syncedindexes_count- количество таблиц, управляемых кластеромindexes- список имен таблиц, управляемых кластеромnodes_set- список узлов в кластере, определённый с помощью командCREATE,JOINилиALTER UPDATEnodes_view- фактический список узлов в кластере, которые видит текущий узелstate_uuid- UUID состояния кластера. Если он совпадает со значением в local_state_uuid, локальные и кластерные узлы синхронизированы.conf_id- общее количество изменений состава кластера.status- статус компонента кластера. Возможные значения: primary (конфигурация основной группы, кворум есть), non_primary (конфигурация неосновной группы, кворум потерян), disconnected (нет подключения к группе, повторная попытка), или recovery-required (метаданные кластера сохранены, но провайдер репликации не запустился и требуется ручное восстановление).size- количество узлов, находящихся в кластере в данный момент.local_index- индекс данного узла в кластере.last_error- последнее зафиксированное сообщение об ошибке, связанной с операцией кластера. Сообщение дает общий обзор проблемы. Для более подробного контекста следует обратиться к файлуsearchd.log.
Когда status равен recovery-required, Manticore сохраняет видимость метаданных кластера и членства таблиц, чтобы вы могли проверить или удалить кластер, но запись в кластер недоступна. Переменные состояния провайдера Galera недоступны, пока кластер не будет восстановлен и запущен снова.
Во время передачи снимка состояния (State Snapshot Transfer, SST) один узел подготавливает другой, передавая полную копию данных. Это происходит, когда новый узел присоединяется к кластеру JOIN CLUSTER или когда добавляются новые таблицы ALTER CLUSTER ADD. Пока активен SST, на обоих узлах - доноре и присоединяющемся - доступны дополнительные переменные статуса, прогресс которых синхронизирован.
cluster_name_sst_total- общий прогресс всей операции SST, от 0 до 100. Это основной счетчик для отслеживания.cluster_name_sst_stage- название текущей фазы работы. Процесс циклично проходит следующие этапы для каждой передаваемой таблицы:await nodes syncblock checksum calculateanalyze remotesend filesactivate tables
cluster_name_sst_stage_total- прогресс текущей стадии, от 0 до 100.cluster_name_sst_tables- общее количество таблиц, передаваемых в SST.cluster_name_sst_table- имя и индекс текущей обрабатываемой таблицы (например,3 (products)).
Для большинства случаев достаточно переменной cluster_name_sst_total. Однако остальные счетчики могут быть полезны при исследовании зависаний или проблем с производительностью на конкретной стадии SST или при передаче конкретной таблицы.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
SHOW STATUSPOST /cli -d "
SHOW STATUS
"$params = [
'body' => []
];
$response = $client->nodes()->status($params);utilsApi.sql('SHOW STATUS')await utilsApi.sql('SHOW STATUS')res = await utilsApi.sql('SHOW STATUS');utilsApi.sql("SHOW STATUS");utilsApi.sql("SHOW STATUS");utils_api.sql("SHOW STATUS", Some(true)).await;+---------------------------------+-------------------------------------------------------------------------------------+
| Counter | Value |
+---------------------------------+-------------------------------------------------------------------------------------+
| cluster_name | post |
| cluster_post_state_uuid | fba97c45-36df-11e9-a84e-eb09d14b8ea7 |
| cluster_post_conf_id | 1 |
| cluster_post_status | primary |
| cluster_post_size | 5 |
| cluster_post_local_index | 0 |
| cluster_post_node_state | donor |
| cluster_post_indexes_count | 2 |
| cluster_post_indexes | pq1,pq_posts |
| cluster_post_nodes_set | 10.10.0.1:9312 |
| cluster_post_nodes_view | 10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication |
| cluster_post_sst_total | 65 |
| cluster_post_sst_stage | send files |
| cluster_post_sst_stage_total | 78 |
| cluster_post_sst_tables | 5 |
| cluster_post_sst_table | 3 (products) |
+---------------------------------+-------------------------------------------------------------------------------------+"
{"columns":[{"Counter":{"type":"string"}},{"Value":{"type":"string"}}],
"data":[
{"Counter":"cluster_name", "Value":"post"},
{"Counter":"cluster_post_state_uuid", "Value":"fba97c45-36df-11e9-a84e-eb09d14b8ea7"},
{"Counter":"cluster_post_conf_id", "Value":"1"},
{"Counter":"cluster_post_status", "Value":"primary"},
{"Counter":"cluster_post_size", "Value":"5"},
{"Counter":"cluster_post_local_index", "Value":"0"},
{"Counter":"cluster_post_node_state", "Value":"donor"},
{"Counter":"cluster_post_indexes_count", "Value":"2"},
{"Counter":"cluster_post_indexes", "Value":"pq1,pq_posts"},
{"Counter":"cluster_post_nodes_set", "Value":"10.10.0.1:9312"},
{"Counter":"cluster_post_nodes_view", "Value":"10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication"},
{"Counter":"cluster_post_sst_total", "Value":"65"},
{"Counter":"cluster_post_sst_stage", "Value":"send files"},
{"Counter":"cluster_post_sst_stage_total", "Value":"78"},
{"Counter":"cluster_post_sst_tables", "Value":"5"},
{"Counter":"cluster_post_sst_table", "Value":"3 (products)"}
],
"total":0,
"error":"",
"warning":""
}(
"cluster_name" => "post",
"cluster_post_state_uuid" => "fba97c45-36df-11e9-a84e-eb09d14b8ea7",
"cluster_post_conf_id" => 1,
"cluster_post_status" => "primary",
"cluster_post_size" => 5,
"cluster_post_local_index" => 0,
"cluster_post_node_state" => "donor",
"cluster_post_indexes_count" => 2,
"cluster_post_indexes" => "pq1,pq_posts",
"cluster_post_nodes_set" => "10.10.0.1:9312",
"cluster_post_nodes_view" => "10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication",
"cluster_post_sst_total" => 65,
"cluster_post_sst_stage" => "send files",
"cluster_post_sst_stage_total" => 78,
"cluster_post_sst_tables" => 5,
"cluster_post_sst_table" => "3 (products)"
){u'columns': [{u'Key': {u'type': u'string'}},
{u'Value': {u'type': u'string'}}],
u'data': [
{u'Key': u'cluster_name', u'Value': u'post'},
{u'Key': u'cluster_post_state_uuid', u'Value': u'fba97c45-36df-11e9-a84e-eb09d14b8ea7'},
{u'Key': u'cluster_post_conf_id', u'Value': u'1'},
{u'Key': u'cluster_post_status', u'Value': u'primary'},
{u'Key': u'cluster_post_size', u'Value': u'5'},
{u'Key': u'cluster_post_local_index', u'Value': u'0'},
{u'Key': u'cluster_post_node_state', u'Value': u'donor'},
{u'Key': u'cluster_post_indexes_count', u'Value': u'2'},
{u'Key': u'cluster_post_indexes', u'Value': u'pq1,pq_posts'},
{u'Key': u'cluster_post_nodes_set', u'Value': u'10.10.0.1:9312'},
{u'Key': u'cluster_post_nodes_view', u'Value': u'10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication'},
{u'Key': u'cluster_post_sst_total', u'Value': u'65'},
{u'Key': u'cluster_post_sst_stage', u'Value': u'send files'},
{u'Key': u'cluster_post_sst_stage_total', u'Value': u'78'},
{u'Key': u'cluster_post_sst_tables', u'Value': u'5'},
{u'Key': u'cluster_post_sst_table', u'Value': u'3 (products)'}],
u'error': u'',
u'total': 0,
u'warning': u''}{u'columns': [{u'Key': {u'type': u'string'}},
{u'Value': {u'type': u'string'}}],
u'data': [
{u'Key': u'cluster_name', u'Value': u'post'},
{u'Key': u'cluster_post_state_uuid', u'Value': u'fba97c45-36df-11e9-a84e-eb09d14b8ea7'},
{u'Key': u'cluster_post_conf_id', u'Value': u'1'},
{u'Key': u'cluster_post_status', u'Value': u'primary'},
{u'Key': u'cluster_post_size', u'Value': u'5'},
{u'Key': u'cluster_post_local_index', u'Value': u'0'},
{u'Key': u'cluster_post_node_state', u'Value': u'donor'},
{u'Key': u'cluster_post_indexes_count', u'Value': u'2'},
{u'Key': u'cluster_post_indexes', u'Value': u'pq1,pq_posts'},
{u'Key': u'cluster_post_nodes_set', u'Value': u'10.10.0.1:9312'},
{u'Key': u'cluster_post_nodes_view', u'Value': u'10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication'},
{u'Key': u'cluster_post_sst_total', u'Value': u'65'},
{u'Key': u'cluster_post_sst_stage', u'Value': u'send files'},
{u'Key': u'cluster_post_sst_stage_total', u'Value': u'78'},
{u'Key': u'cluster_post_sst_tables', u'Value': u'5'},
{u'Key': u'cluster_post_sst_table', u'Value': u'3 (products)'}],
u'error': u'',
u'total': 0,
u'warning': u''}{"columns": [{"Key": {"type": "string"}},
{"Value": {"type": "string"}}],
"data": [
{"Key": "cluster_name", "Value": "post"},
{"Key": "cluster_post_state_uuid", "Value": "fba97c45-36df-11e9-a84e-eb09d14b8ea7"},
{"Key": "cluster_post_conf_id", "Value": "1"},
{"Key": "cluster_post_status", "Value": "primary"},
{"Key": "cluster_post_size", "Value": "5"},
{"Key": "cluster_post_local_index", "Value": "0"},
{"Key": "cluster_post_node_state", "Value": "donor"},
{"Key": "cluster_post_indexes_count", "Value": "2"},
{"Key": "cluster_post_indexes", "Value": "pq1,pq_posts"},
{"Key": "cluster_post_nodes_set", "Value": "10.10.0.1:9312"},
{"Key": "cluster_post_nodes_view", "Value": "10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication"},
{"Key": "cluster_post_sst_total", "Value": "65"},
{"Key": "cluster_post_sst_stage", "Value": "send files"},
{"Key": "cluster_post_sst_stage_total", "Value": "78"},
{"Key": "cluster_post_sst_tables", "Value": "5"},
{"Key": "cluster_post_sst_table", "Value": "3 (products)"}],
"error": "",
"total": 0,
"warning": ""}{columns=[{ Key : { type=string }},
{ Value : { type=string }}],
data : [
{ Key=cluster_name, Value=post},
{ Key=cluster_post_state_uuid, Value=fba97c45-36df-11e9-a84e-eb09d14b8ea7},
{ Key=cluster_post_conf_id, Value=1},
{ Key=cluster_post_status, Value=primary},
{ Key=cluster_post_size, Value=5},
{ Key=cluster_post_local_index, Value=0},
{ Key=cluster_post_node_state, Value=donor},
{ Key=cluster_post_indexes_count, Value=2},
{ Key=cluster_post_indexes, Value=pq1,pq_posts},
{ Key=cluster_post_nodes_set, Value=10.10.0.1:9312},
{ Key=cluster_post_nodes_view, Value=10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication},
{ Key=cluster_post_sst_total, Value=65},
{ Key=cluster_post_sst_stage, Value=send files},
{ Key=cluster_post_sst_stage_total, Value=78},
{ Key=cluster_post_sst_tables, Value=5},
{ Key=cluster_post_sst_table, Value=3 (products)}],
error= ,
total=0,
warning= }{columns=[{ Key : { type=String }},
{ Value : { type=String }}],
data : [
{ Key=cluster_name, Value=post},
{ Key=cluster_post_state_uuid, Value=fba97c45-36df-11e9-a84e-eb09d14b8ea7},
{ Key=cluster_post_conf_id, Value=1},
{ Key=cluster_post_status, Value=primary},
{ Key=cluster_post_size, Value=5},
{ Key=cluster_post_local_index, Value=0},
{ Key=cluster_post_node_state, Value=donor},
{ Key=cluster_post_indexes_count, Value=2},
{ Key=cluster_post_indexes, Value=pq1,pq_posts},
{ Key=cluster_post_nodes_set, Value=10.10.0.1:9312},
{ Key=cluster_post_nodes_view, Value=10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication},
{ Key=cluster_post_sst_total, Value=65},
{ Key=cluster_post_sst_stage, Value=send files},
{ Key=cluster_post_sst_stage_total, Value=78},
{ Key=cluster_post_sst_tables, Value=5},
{ Key=cluster_post_sst_table, Value=3 (products)}],
error="" ,
total=0,
warning="" }{columns=[{ Key : { type=String }},
{ Value : { type=String }}],
data : [
{ Key=cluster_name, Value=post},
{ Key=cluster_post_state_uuid, Value=fba97c45-36df-11e9-a84e-eb09d14b8ea7},
{ Key=cluster_post_conf_id, Value=1},
{ Key=cluster_post_status, Value=primary},
{ Key=cluster_post_size, Value=5},
{ Key=cluster_post_local_index, Value=0},
{ Key=cluster_post_node_state, Value=donor},
{ Key=cluster_post_indexes_count, Value=2},
{ Key=cluster_post_indexes, Value=pq1,pq_posts},
{ Key=cluster_post_nodes_set, Value=10.10.0.1:9312},
{ Key=cluster_post_nodes_view, Value=10.10.0.1:9312,10.10.0.1:9320:replication,10.10.1.1:9312,10.10.1.1:9320:replication},
{ Key=cluster_post_sst_total, Value=65},
{ Key=cluster_post_sst_stage, Value=send files},
{ Key=cluster_post_sst_stage_total, Value=78},
{ Key=cluster_post_sst_tables, Value=5},
{ Key=cluster_post_sst_table, Value=3 (products)}],
error="" ,
total=0,
warning="" }Когда весь кластер репликации из нескольких узлов лежит, первым нужно запустить один узел, чтобы остальные узлы знали, к какой копии кластера присоединяться.
Есть одно исключение при обычном запуске: если кластер уже стал чистым однузловым кластером, например после того, как остальные узлы вышли с помощью EXIT CLUSTER, запустите этот оставшийся узел обычным способом. После корректного завершения работы Manticore восстанавливает такой кластер, состоящий только из него самого, как primary / synced без --new-cluster.
Решение о том, какой узел запустить первым, основывается на файле grastate.dat — небольшом файле состояния репликации, хранящемся в каталоге данных кластера. Наиболее важные поля:
seqno— номер последней известной этому узлу транзакцииsafe_to_bootstrap— помечен ли этот узел как безопасный для первого запуска после чистого завершения работы
Пример того, как может выглядеть grastate.dat после чистого завершения работы:
# saved replication state
version: 2.1
uuid: <cluster-uuid>
seqno: 12345
safe_to_bootstrap: 1
В этом примере:
seqno: 12345означает, что этот узел знает о транзакциях вплоть до порядкового номера 12345safe_to_bootstrap: -1означает, что этот узел помечен как безопасный для первого запуска
Если весь кластер был корректно остановлен, запустите узел, который был остановлен последним. На практике это обычно узел с:
- наибольшим значением
seqno safe_to_bootstrap: 1
Запустите этот узел первым. Это укажет Manticore начать новую копию кластера с этого узла. После этого запустите оставшиеся узлы обычным образом, чтобы они могли повторно присоединиться.
Используйте это после чистого полного отключения кластера.
- Bash
- Systemd
searchd --new-clustermanticore_new_clusterЕсли другой узел будет запущен первым без требуемого состояния чистого завершения работы, запуск будет отклонен для защиты кластера от восстановления из более старой копии.
Если все узлы аварийно завершили работу или были остановлены некорректно, файл grastate.dat может больше не быть надежным для обычного выбора начальной загрузки. В этом случае найдите узел с самыми свежими данными, обычно тот, у которого наибольший seqno, и запустите его с опцией --new-cluster-force. Это отменяет обычную защиту и принудительно запускает кластер с выбранного узла.
Используйте это после аварийного или некорректного полного отключения кластера.
- Bash
- Systemd
searchd --new-cluster-forcemanticore_new_cluster --forceЕсли репликационный узел или весь кластер становится недоступным, правильная процедура восстановления зависит от того, сколько узлов остаются доступными и был ли останов чистым или внезапным.
Репликационный кластер следует рассматривать как одну логическую систему, а не набор независимых серверов. Это обеспечивает многомастерные записи и согласованность данных, но также означает, что вы должны осторожно восстанавливать кворум. В частности, не запускайте команду ручного восстановления, которая восстанавливает записи на сохранившейся стороне, пока не убедитесь, что пропавшие узлы действительно отсутствуют. Эта команда показана далее на этой странице как 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 и ожидаемый размер кластера, прежде чем считать восстановление завершенным.
Если узлы A и B были намеренно удалены из кластера, например с помощью EXIT CLUSTER, и узел C теперь является единственным сохранённым узлом в кластере, узел C также может восстановиться после собственного чистого перезапуска при обычном запуске демона. В этом случае, когда он один, --new-cluster не требуется.
Если все узлы в многонодовом кластере были штатно остановлены, кластер полностью недоступен и его нужно снова запустить особым образом, чтобы один узел мог стать первым запущенным узлом кластера.
При чистой остановке каждый узел записывает свой последний номер транзакции в 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 должен быть вашим первым выбором.
Используйте эту процедуру только в крайнем случае, когда ни один узел не может восстановить кластер обычными способами, описанными выше, но таблицы кластера по-прежнему присутствуют в локальных каталогах данных. Это может случиться, если сохранённые метаданные кластера неполные или несовместимы с запущенной версией, либо если другая ошибка запуска делает старое членство в кластере непригодным для использования.
Эта процедура создаёт новый кластер. Она отбрасывает старое членство в кластере и историю репликации, а затем копирует таблицы с одного выбранного узла на другие узлы. Не используйте её, пока на каком-либо узле ещё есть исправная копия старого кластера в состоянии primary / synced. В этом случае сохраните исправный кластер и восстановите остальные узлы через JOIN CLUSTER.
-
Остановите Manticore на каждом узле, который входил в сбойный кластер. Не записывайте данные в локальные таблицы во время этой процедуры.
-
Сделайте резервную копию всего
data_dirна каждом узле. Сохраните копию старого дескриптора кластера, если в нём есть пользовательскиеpath,nodesилиoptionsпоставщика, которые вам нужны при воссоздании кластера. -
Выберите узел, чьи локальные таблицы содержат данные, которые нужно сохранить. Этот узел станет источником для нового кластера. Если позже добавить его таблицы в кластер, таблицы с теми же именами на других узлах будут заменены.
-
На каждом узле отредактируйте
<data_dir>/manticore.json. В верхнеуровневом объектеclustersудалите только запись для сбойного кластера. Например, удалитеclusters.postsдля кластера с именемposts.Оставьте объект
indexesи каждый каталог таблицы на месте. Не удаляйте и не создавайте таблицы заново. -
Запустите Manticore обычным образом на каждом узле. Бывшие таблицы кластера должны теперь отображаться как локальные таблицы. Проверьте таблицы на выбранном исходном узле, прежде чем продолжать. Если они отсутствуют или неполные, остановитесь и восстановите резервную копию.
-
На выбранном исходном узле создайте кластер. Укажите любые сохранённые
path,nodesили параметры поставщика, если они по-прежнему нужны. Если включена аутентификация, добавьте'<replication-user>' AS userв этот оператор и в операторыJOIN CLUSTERниже. У учётной записи должны совпадать сохранённые данные аутентификации и правоreplicationна каждом узле. См. настройку репликации.CREATE CLUSTER posts -
На каждом другом узле подключите новый кластер через первый узел:
JOIN CLUSTER posts AT 'node-a.example:9312' -
На выбранном исходном узле присоедините существующие локальные таблицы к новому кластеру:
ALTER CLUSTER posts ADD table_a, table_b -
Дождитесь, пока каждый узел не сообщит
cluster_posts_status=primaryиcluster_posts_node_state=synced, прежде чем возобновлять запись.
Если узел 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' = 1POST /cli -d "
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' = 1POST /cli -d "
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1
"Никогда не выполняйте этот оператор на обеих сторонах. Если вы это сделаете, вы создадите два отдельных основных кластера, и они не объединятся автоматически при восстановлении сети.
В локальном тестировании внезапная потеря половины четырехузлового кластера воспроизвела то же поведение non-primary, и та же команда восстановления вернула одну выжившую половину в состояние primary.