Запросы и ответы репликации
В этом разделе описаны внутренние запросы и ответы, передаваемые в процессе репликации. Каждый из них отличается заголовком, содержащим уникальное значение IPROTO_REQUEST_TYPE. Эти значения и соответствующие структуры тела пакета рассмотрены ниже.
Коннекторы и клиенты не должны отправлять пакеты репликации.
Name | Code | Description |
|---|---|---|
0x41 | Запрос на присоединение к набору реплик | |
0x42 | Запрос на подписку на конкретный узел в наборе реплик | |
0x44 | Запрос для репликации | |
0x29 | Ответ на IPROTO_VOTE. Используется при начальной загрузке набора реплик | |
0x45 | Получение снимка мастера и запуск анонимной репликации. | |
0x46 | Регистрация анонимной реплики, после которой она перестает быть анонимной | |
0x47 | Запрос, отправляемый в ответ на IPROTO_JOIN или IPROTO_FETCH_SNAPSHOT перед информацией об инициализации экземпляра | |
0x48 | Запрос, отправляемый в ответ на IPROTO_JOIN или IPROTO_FETCH_SNAPSHOT после информации об инициализации экземпляра |
Мастер также отправляет репликам сообщения heartbeat.
Значение IPROTO_REQUEST_TYPE для сообщения heartbeat – 0.
Ниже приведены сведения об отдельных запросах репликации. Информацию о запросах синхронной репликации см. в разделе синхронных запросах.
Каждые replication_timeout секунд мастер отправляет реплике сообщение heartbeat, а реплика отправляет ответ. Значение IPROTO_REQUEST_TYPE обоих сообщений – IPROTO_OK. IPROTO_TIMESTAMP – 8-байтовая метка времени в формате float-64 MP_DOUBLE.
Начиная с версии 2.11 оба сообщения содержат необязательное поле в теле с ключом IPROTO_VCLOCK_SYNC. Если ключ IPROTO_VCLOCK_SYNC опущен, heartbeat-сообщение мастера не содержит тела.
Сообщение от мастера к реплике:
Ответ реплики:
В руководстве Understanding the binary protocol показаны фактические байтовые коды приведенных выше примеров heartbeat-сообщений.
Код: 0x41.
Для присоединения к набору реплик экземпляр должен отправить начальный запрос IPROTO_JOIN мастеру набора реплик:
Экземпляр, получивший запрос, отправляет в ответ следующие сообщения:
-
Свой vclock:
-
(Необязательно) Последовательность запросов с информацией, необходимой для инициализации экземпляра:
- запрос IPROTO_JOIN_META
- запрос IPROTO_RAFT с полями IPROTO_RAFT_TERM и IPROTO_RAFT_VOTE
- запрос IPROTO_RAFT_PROMOTE
- запрос IPROTO_JOIN_SNAPSHOT
Этот шаг выполняется, если указанная в запросе версия IPROTO_SERVER_VERSION –
2.10или выше. -
Несколько запросов INSERT (с дополнительными LSN и ServerID). Таким образом данные обновляются на экземпляре, отправившем запрос IPROTO_JOIN. Экземпляр не должен отвечать на эти запросы INSERT.
-
MP_MAP с новым vclock в ответе, аналогичном приведенному выше.
-
Несколько запросов INSERT, REPLACE, UPDATE, UPSERT и DELETE. Таким образом экземпляр, присоединяющийся к набору реплик, получает обновления данных, произошедшие на этапе присоединения.
-
MP_MAP с новым vclock в ответе, аналогичном приведенному выше.
Код: 0x42.
Если запрос IPROTO_JOIN выполнен успешно, экземпляр-инициатор должен отправить запрос IPROTO_SUBSCRIBE всем узлам, указанным в box.cfg.replication:
После успешного запроса IPROTO_SUBSCRIBE экземпляр должен обрабатывать каждый запрос, который может поступить от других мастеров. Каждый запрос мастера содержит пару значений vclock, соответствующую этому мастеру – идентификатор экземпляра и LSN, независимые от других мастеров.
IPROTO_ID_FILTER (0x51) – необязательный ключ, используемый в запросе SUBSCRIBE, за которым следует массив идентификаторов экземпляров, строки которых не будут переданы реплике. Поле кодируется только в том случае, если список идентификаторов не пуст.
Код: 0x45.
Для присоединения к набору реплик в качестве анонимной реплики экземпляр должен отправить начальный запрос IPROTO_FETCH_SNAPSHOT мастеру набора реплик:
Подробнее об анонимных репликах см. в replication.anon.
Экземпляр, получивший запрос, отправляет в ответ следующие сообщения:
-
Свой vclock:
-
(Необязательно) Последовательность запросов с информацией, необходимой для инициализации экземпляра:
- запрос IPROTO_JOIN_META
- запрос IPROTO_RAFT с полями IPROTO_RAFT_TERM и IPROTO_RAFT_VOTE
- запрос IPROTO_RAFT_PROMOTE
- запрос IPROTO_JOIN_SNAPSHOT
Этот шаг выполняется, если указанная в запросе версия IPROTO_SERVER_VERSION –
2.10или выше. -
Несколько запросов INSERT (с дополнительными LSN и ServerID). Таким образом данные обновляются на экземпляре, отправившем запрос IPROTO_JOIN. Экземпляр не должен отвечать на эти запросы INSERT.
-
MP_MAP с новым vclock в ответе, аналогичном приведенному выше.
Код: 0x46.
Для регистрации анонимной реплики в наборе реплик, после чего она перестает быть анонимной, необходимо отправить запрос IPROTO_REGISTER мастеру набора реплик:
Экземпляр, получивший запрос, отправляет в ответ следующие сообщения:
- Несколько запросов INSERT, REPLACE, UPDATE, UPSERT и DELETE. Таким образом экземпляр, регистрирующийся в наборе реплик, получает обновления данных, произошедшие с момента получения снимка.
- MP_MAP с новым vclock.
Технически последующие запросы IPROTO_FETCH_SNAPSHOT и IPROTO_REGISTER эквивалентны запросу IPROTO_JOIN.
Код: 0x47.
При получении запроса IPROTO_JOIN или IPROTO_FETCH_SNAPSHOT ответы включают информацию, необходимую для инициализации экземпляра: текущий Raft-терм, текущее состояние очереди синхронных транзакций. Перед отправкой этой информации экземпляр отправляет запрос IPROTO_JOIN_META с пустым телом:
Подробнее см. в IPROTO_JOIN
Код: 0x48.
Экземпляр, получивший запрос IPROTO_JOIN или IPROTO_FETCH_SNAPSHOT, отправляет запрос IPROTO_JOIN_SNAPSHOT с пустым телом после завершения отправки информации об инициализации экземпляра.
Подробнее см. в IPROTO_JOIN
Код: 0x44.
При подключении для репликации экземпляр отправляет запрос IPROTO_VOTE. Тело запроса отсутствует:
IPROTO_VOTE играет ключевую роль при начальной загрузке набора реплик. Ответом на этот запрос является IPROTO_BALLOT.
Код: 0x29.
Это значение IPROTO_REQUEST_TYPE указывает на сообщение, отправляемое в ответ на IPROTO_VOTE (не путать с ключом IPROTO_RAFT_VOTE).
IPROTO_BALLOT и IPROTO_VOTE играют ключевую роль при начальной загрузке набора реплик. IPROTO_BALLOT соответствует карте (map), содержащей следующие поля:
IPROTO_BALLOT_REGISTERED_REPLICA_UUIDS имеет тип MP_ARRAY. Массив содержит элементы MP_STR.
Name | Code | Description |
|---|---|---|
0x1e | Уведомление об изменении статуса RAFT узла | |
0x1f | Ожидание и выбор нового лидера репликации | |
0x20 | Отзыв роли лидера у экземпляра | |
0x28 | Подтверждение того, что RAFT-транзакции достигли кворума и могут быть зафиксированы | |
0x29 | Откат RAFT-транзакций, так как они не достигли кворума |
Код: 0x1e.
Узел рассылает запрос IPROTO_RAFT всем подключенным к нему репликам при изменении состояния RAFT узла. Это может быть любое действие, изменяющее состояние: начало новых выборов, увеличение терма, голосование за другой узел, назначение лидером и т.д.
Если ожидается ответ, например, в случае запроса на голосование другим узлам, ответом также будет сообщение IPROTO_RAFT. В этом случае узел должен быть подключен как реплика к другому узлу, от которого ожидается ответ, поскольку ответ передается через канал репликации. Иными словами, между узлами должно быть установлено полносвязное соединение (full mesh).
IPROTO_REPLICA_ID – идентификатор реплики, от которой поступил запрос.
Код: 0x1f.
См. box.ctl.promote().
В заголовке:
- IPROTO_REPLICA_ID – идентификатор реплики узла, отправившего запрос.
- IPROTO_LSN – фактический LSN операции promote, записанный в WAL.
В теле:
- IPROTO_REPLICA_ID – идентификатор реплики предыдущего владельца синхронной очереди.
- IPROTO_LSN – LSN последней операции предыдущего владельца синхронной очереди.
- IPROTO_TERM – терм, в котором узел, отправивший запрос, становится владельцем синхронной очереди. Этот терм соответствует значению box.info.synchro.queue.term на экземпляре.
Код: 0x20.
См. box.ctl.demote().
В заголовке:
- IPROTO_REPLICA_ID – идентификатор реплики узла, отправившего запрос.
- IPROTO_LSN – фактический LSN операции demote, записанный в WAL.
В теле:
- IPROTO_REPLICA_ID – идентификатор реплики узла, отправившего запрос (совпадает со значением в заголовке).
- IPROTO_LSN – LSN последней синхронной транзакции, записанной в WAL узла.
- IPROTO_TERM – терм, в котором очередь становится пустой.
Код: 0x28.
Это сообщение используется в соединениях репликации между узлами Tarantool при синхронной репликации. Оно не предназначено для использования клиентскими приложениями в их обычных соединениях.
Это сообщение подтверждает, что транзакции, инициированные экземпляром с идентификатором id = IPROTO_REPLICA_ID (тело), достигли кворума и могут быть зафиксированы вплоть до LSN = IPROTO_LSN (тело) включительно.
Тело представляет собой карту (map) из двух элементов:
В заголовке:
- IPROTO_REPLICA_ID – идентификатор реплики, отправляющей сообщение подтверждения.
- IPROTO_LSN – LSN действия подтверждения.
В теле:
- IPROTO_REPLICA_ID – идентификатор экземпляра, от которого исходят транзакции.
- IPROTO_LSN – LSN, до которого (включительно) должны быть подтверждены транзакции.
До Tarantool 2.10.0 IPROTO_RAFT_CONFIRM назывался IPROTO_CONFIRM.
Код: 0x29.
Это сообщение используется в соединениях репликации между узлами Tarantool при синхронной репликации. Оно не предназначено для использования клиентскими приложениями в их обычных соединениях.
Это сообщение указывает, что транзакции, инициированные экземпляром с идентификатором id = IPROTO_REPLICA_ID (тело), по какой-то причине не достигли кворума и должны быть откачены вплоть до LSN = IPROTO_LSN (тело) включительно.
Тело представляет собой карту (map) из двух элементов:
В заголовке:
- IPROTO_REPLICA_ID – идентификатор реплики, отправляющей сообщение отката.
- IPROTO_LSN – LSN действия отката.
В теле:
- IPROTO_REPLICA_ID – идентификатор экземпляра, от которого исходят транзакции.
- IPROTO_LSN – LSN, начиная с которого все ожидающие синхронные транзакции должны быть откачены.
До Tarantool 2.10.0 IPROTO_RAFT_ROLLBACK назывался
IPROTO_ROLLBACK.