Оператор 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.
Во время передачи снимка состояния (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="" }В кластере с мульти-мастер репликацией необходимо установить опорную точку, прежде чем другие узлы смогут присоединиться и сформировать кластер. Это называется инициализацией кластера и включает запуск одного узла как 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 присоединяется к кластеру и не будет обслуживать транзакции записи, пока полностью не синхронизируется с кластером. Если кэш 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' = 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.
Split-brain может привести к переходу кластера в состояние неосновного узла. Например, рассмотрим кластер, состоящий из четного числа узлов (четыре), таких как две пары узлов, расположенных в разных дата-центрах. Если сетевая ошибка прерывает соединение между дата-центрами, возникает split-brain, так как каждая группа узлов удерживает ровно половину кворума. В результате обе группы прекращают обработку транзакций записи, поскольку модель репликации Galera отдает приоритет согласованности данных, и кластер не может принимать транзакции записи без кворума. Однако узлы в обеих группах пытаются переподключиться к узлам из другой группы в попытке восстановить кластер.
Если кто-то хочет восстановить кластер до восстановления сети, следует выполнить те же шаги, описанные в Case 5, но только для одной группы узлов.
После выполнения оператора группа с узлом, на котором он был выполнен, сможет снова обрабатывать транзакции записи.
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1POST /cli -d "
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1
"Однако важно отметить, что если оператор будет выполнен в обеих группах, это приведет к формированию двух отдельных кластеров, и последующее восстановление сети не приведет к повторному объединению групп.