Оператор 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":""}Например, при первоначальном создании кластера список узлов, используемых для повторного присоединения к кластеру, был 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на любом другом узле.
После этих шагов другие узлы забудут об отсоединенном узле, а отсоединенный узел забудет о кластере. Это действие не повлияет на таблицы в кластере или на отсоединенном узле.
Вы можете просмотреть информацию о статусе кластера, проверив статус узла. Это можно сделать с помощью команды 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 (отсутствует соединение с группой, повтор попытки).size- количество узлов, находящихся в кластере в данный момент.local_index- индекс данного узла в кластере.last_error- последнее зафиксированное сообщение об ошибке, связанной с операцией кластера. Сообщение дает общий обзор проблемы. Для более подробного контекста следует обратиться к файлуsearchd.log.
Во время передачи снимка состояния (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="" }В кластере с многомастеровой репликацией необходимо установить отправную точку, прежде чем другие узлы смогут присоединиться и сформировать кластер. Это называется загрузкой кластера (bootstrap) и включает запуск одного узла в качестве primary component. Перезапуск одного узла или повторное подключение после отключения можно выполнять как обычно.
В случае полного отключения кластера первый должен быть запущен сервер, который был остановлен последним, с параметром командной строки --new-cluster или путем запуска manticore_new_cluster через systemd. Чтобы гарантировать, что сервер может служить отправной точкой, файл grastate.dat, расположенный в папке кластера, должен содержать значение 1 для опции safe_to_bootstrap. Обе условия, --new-cluster и safe_to_bootstrap=1, должны быть выполнены. Если любой другой узел будет запущен без этих параметров, возникнет ошибка. Для обхода этой защиты и принудительного запуска кластера с другого сервера можно использовать параметр командной строки --new-cluster-force. Альтернативно можно запустить manticore_new_cluster --force через systemd.
В случае жесткого сбоя или некорректного завершения работы всех серверов в кластере следует определить наиболее продвинутый узел с наибольшим значением seqno в файле grastate.dat, расположенном в папке кластера, и запустить его с ключом командной строки --new-cluster-force.
В случае, если демон поиска Manticore останавливается и в кластере не остается узлов для обработки запросов, необходимо выполнить восстановление. Из-за мульти-мастерной природы библиотеки Galera, используемой для репликации, кластер репликации Manticore представляет собой единый логический объект, который поддерживает согласованность своих узлов и данных, а также состояние всего кластера. Это позволяет безопасно проводить записи на нескольких узлах одновременно и обеспечивает целостность кластера.
Однако это также создает некоторые сложности. Рассмотрим несколько сценариев, используя кластер из узлов A, B и C, чтобы понять, что нужно делать, когда некоторые или все узлы становятся недоступными.
Когда узел A останавливается, другие узлы получают сообщение о «нормальном завершении работы». Размер кластера уменьшается, и происходит перерасчет кворума.
При запуске узел A присоединяется к кластеру и не будет обслуживать операции записи, пока полностью не синхронизируется с кластером. Если кэш набора транзакций на узлах-доноров 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 и получит файлы таблиц, в которых некоторые транзакции отсутствуют по сравнению с теми файлами таблиц, которые он имел ранее. Поэтому важно запускать в первую очередь узел, который был остановлен последним, и у которого в файле grastate.dat установлен флаг safe_to_bootstrap: 1.
В случае сбоя или сетевого отказа, из-за которого узел 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' = 1POST /cli -d "
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.
Разделение мозга может привести к переходу кластера в состояние без первичной реплики. Например, рассмотрим кластер, состоящий из четного числа узлов (четыре), таких как две пары узлов, расположенных в разных центрах обработки данных. Если сбой сети прерывает соединение между центрами обработки данных, происходит разделение мозга, поскольку каждая группа узлов удерживает ровно половину кворума. В результате обе группы перестают обрабатывать транзакции записи, поскольку модель репликации Galera отдает приоритет согласованности данных, и кластер не может принимать транзакции записи без кворума. Однако узлы в обеих группах пытаются переподключиться к узлам из другой группы, чтобы восстановить кластер.
Если кто-то хочет восстановить кластер до восстановления сети, следует предпринять те же шаги, что описаны в Случае 5, но только в одной группе узлов.
После выполнения оператора группа с узлом, на котором он был выполнен, снова сможет обрабатывать транзакции записи.
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1POST /cli -d "
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1
"Однако важно отметить, что если оператор будет выполнен в обеих группах, это приведет к образованию двух отдельных кластеров, и последующее восстановление сети не приведет к повторному объединению групп.