Перейти к содержанию

Интерфейс RPC API

В данном документе описан Интерфейс RPC API — основной интерфейс взаимодействия с инстансом Picodata. Вызов RPC-функций происходит по протоколу iproto через коннектор net.box или любой другой.

RPC API используется в следующих сценариях:

  • Внешние системы могут вызывать функции через коннектор
  • Инстансы взаимодействуют друг с другом под служебной учетной записью pico_service
  • Тестирование pytest использует для подключения клиент tarantool-python
  • Подключение picodata connect использует вызов .proc_sql_dispatch

Детали реализации

Функции RPC API представляют собой хранимые процедуры Tarantool box.func. Аргументы и возвращаемые значения функций описаны в системе типов msgpack.

Особенности энкодинга

  • optional-поле (например optional MP_INT) отличается от обычного тем, что на его месте может присутствовать как ожидаемый msgpack-тип (MP_INT), так и MP_NIL. Тем не менее, при формировании запроса, нельзя пропускать это поле. При отсутствии значения всегда должен быть указан MP_NIL.

  • в случае успешного выполнения RPC-функции (IPROTO_OK) возвращаемое msgpack-значение всегда дополнительно обернуто в MP_ARRAY.

  • в случае ошибки выполнения RPC-функции (Result::Err в терминах Rust) в ответе будет iproto-сообщение с типом IPROTO_TYPE_ERROR, содержащее в себе описание ошибки.

Привилегии

Хранимые процедуры Tarantool не входят в модель управления доступом Picodata. На них невозможно выдать или отозвать привилегии. Авторизация запросов происходит по следующему принципу:

  • функции public доступны для роли public, которая автоматически выдается всем новым пользователям. В этом случае авторизуется не вызов функции, а сам запрос

  • привилегиями на вызов остальных функций обладают Администратор СУБД (admin) и служебная учетная запись pico_service

Public API

.proc_version_info

fn proc_version_info() -> VersionInfo

Возвращает информацию о версиях Picodata и отдельных ее компонентах.

Возвращаемое значение:

  • (MP_MAP VersionInfo):

    • picodata_version: (MP_STR) версия Picodata

    • rpc_api_version: (MP_STR) версия RPC API согласно семантическому версионированию Semantic Versioning

.proc_sql_dispatch

fn proc_sql_dispatch(pattern, params) -> Result

Выполняет распределенный SQL-запрос.

Аргументы:

Возвращаемое значение:

  • (MP_MAP DqlResult) при чтении данных
    Поля:
    • metadata (MP_ARRAY), массив описаний столбцов таблицы в формате MP_ARRAY [ MP_MAP { name = MP_STR, type = MP_STR }, ...]
    • rows (MP_ARRAY), результат выполнения читающего запроса в формате MP_ARRAY [ MP_ARRAY row, ...]
  • (MP_MAP DmlResult) при модификации данных
    Поля:
    • row_count (MP_INT), количество измененных строк

См. также:

Service API

.proc_apply_schema_change

fn proc_apply_schema_change(term, applied, timeout) -> Result

Дожидается момента, когда raft применит запись с заданным индексом и термом перед тем как делать что-то еще, чтобы синхронизировать состояние глобальных системных таблиц. Возвращает ошибку, если времени не хватило.

Применяет текущие изменения глобальной схемы к локальному состоянию инстанса.

Этy хранимую процедуру вызывает только governor в рамках алгоритма отказоустойчивой смены кластерной схемы данных.

Текущие изменения схемы инстанс читает из системной таблицы _pico_property. В ней по ключам pending_schema_change и pending_schema_version соответственно находятся описание текущей DDL-операции и версия глобальной схемы после применения этой операции.

В случае если изменение не применимо на текущем инстансе из-за конфликта хранимых данных, в ответ посылается сообщение с причиной конфликта.

Параметры:

  • term: (MP_INT RaftTerm)
  • applied: (MP_INT RaftIndex)
  • timeout: (MP_INT | MP_FLOAT) в секундах

Возвращаемое значение:

  • Ok: отсутствует
  • Abort: cause (MP_MAP ErrorInfo):
    • error_code: (MP_INT)
    • message: (MP_STR)
    • instance_name: (MP_STR)

.proc_cas

fn proc_cas(cluster_name, predicate, op, as_user) -> (RaftIndex, RaftTerm)

Выполняется только на raft-лидере, в противном случае немедленно возвращает ошибку.

Исполняет кластерную операцию compare-and-swap.

Проверяет предикат. Если проверка не выявляет конфликтов, то добавляет новую запись в raft-журнал и возвращает ее индекс (пока еще не зафиксированный в кластере). Операция применяется только для глобальных таблиц и работает на всем кластере.

Предикат состоит из трех частей:

  • индекс записи в raft-журнале;
  • номера терма;
  • диапазона значений самого проверяемого параметра (ranges).

Диапазон ranges опционален, так как Picodata автоматически проверяет диапазон значений на основе запрашиваемой операции. Возможность указать ranges явно позволяет добавить проверку дополнительных значений (например, если они не изменяются операцией, но неявно могут влиять на нее).

Параметры:

  • cluster_name: (MP_STR)
  • predicate: (MP_MAP Predicate)
  • op: (MP_MAP Op)
  • as_user: (MP_INT)

Возвращаемое значение:

  • index: (MP_INT) raft-индекс
  • term: (MP_INT) raft-терм

.proc_discover

fn proc_discover(request, request_to) -> Result

Этy хранимую процедуру вызывают инстансы Picodata во время запуска с пустым состоянием (bootstrap) в рамках реализации алгоритма discovery.

Параметры:

  • request: (MP_MAP):
    • tmp_id: (MP_STR)
    • peers: (MP_ARRAY of MP_STR)
  • request_to: (MP_STR) адрес, по которому доступен текущий инстанс

Возвращаемое значение:

  • LeaderElection: (MP_MAP LeaderElection) — если алгоритм продолжается:
    • tmp_id: (MP_STR)
    • peers: (MP_ARRAY of MP_STR)
  • Done: (MP_MAP Role) — если результат уже известен:
    • leader_address: (MP_STR) адрес лидера

.proc_expel

fn proc_expel(cluster_name, instance_uuid)

Выполняется только на raft-лидере, в противном случае немедленно возвращает ошибку.

Удаляет указанный инстанс из кластера. На его место в будущем может прийти инстанс с тем же instance_name, однако raft_id уходящего инстанса больше никогда не будет использоваться.

Параметры:

  • cluster_name: (MP_STR)
  • instance_uuid: (MP_STR)

.proc_expel_redirect

fn proc_expel_redirect(cluster_name, instance_uuid)

Вызывает proc_expel на текущем raft-лидере.

Параметры:

  • cluster_name: (MP_STR)
  • instance_uuid: (MP_STR)

.proc_get_config

fn proc_get_config() -> Result

Возвращает совокупную конфигурацию инстанса, в которой для каждого параметра указано значение value и его источник source.

Возможные типы данных:

  • value: (MP_MAP | MP_INT | MP_STR | MP_BOOL | MP_ARRAY | MP_FLOAT)
  • source: (MP_STR)

Возможные источники значений параметров — поле source:

Возвращаемое значение:

.proc_get_index

fn proc_get_index() -> RaftIndex

Возвращает текущий примененный (applied) индекс raft-журнала.

Возвращаемое значение:

  • (MP_INT RaftIndex)

.proc_get_vclock

fn proc_get_vclock() -> Vclock

Возвращает текущее значение Vclock.

Возвращаемое значение:

  • (MP_MAP Vclock)

.proc_get_vshard_config

fn proc_get_vshard_config(tier_name) -> Result

Возвращает Vshard-конфигурацию тира tier_name. Если тир не указан, возвращается Vshard-конфигурация тира текущего инстанса.

Возвращаемое значение:

  • (MP_MAP VshardConfig)

.proc_instance_info

fn proc_instance_info(instance_name) -> InstanceInfo

Возвращает информацию о запрашиваемом инстансе из кластера.

При вызове без параметров возвращает информацию о текущем инстансе.

Аргументы:

  • instance_name: (optional MP_STR)

Возвращаемое значение:

  • (MP_MAP InstanceInfo):
    • raft_id: (MP_UINT)
    • advertise_address: (MP_STR)
    • name: (MP_STR)
    • uuid: (MP_STR)
    • replicaset_name: (MP_STR)
    • replicaset_uuid: (MP_STR)
    • cluster_name: (MP_STR)
    • current_state: (MP_MAP State) — текущее состояние инстанса
      формат: MP_MAP { variant = MP_STR, incarnation = MP_UINT}
      возможные значения variant: Offline, Online, Expelled
    • target_state: (MP_MAP State) — целевое состояние инстанса
    • tier: (MP_STR)

.proc_raft_info

fn proc_raft_info() -> RaftInfo

Возвращает информацию о состоянии raft-узла на текущем инстансе.

Возвращаемое значение:

  • (MP_MAP RaftInfo):
    • id: (MP_INT) raft_id текущего узла
    • term: (MP_INT) текущий терм
    • applied: (MP_INT) текущий примененный индекс raft-журнала
    • leader_id: (MP_INT) raft_id лидера или 0 если в текущем терме его нет
    • state (MP_STR)
      возможные значения: Follower, Candidate, Leader, PreCandidate

.proc_raft_interact

fn proc_raft_interact(raft_messages)

Этy хранимую процедуру вызывают все инстансы Picodata для передачи внутренних сообщений друг другу в рамках реализации алгоритма raft.

Параметры:

  • raft_messages: (MP_ARRAY of MP_ARRAY)

.proc_raft_join

fn proc_raft_join(cluster_name, instance_name, replicaset_name, advertise_address, failure_domain, tier) -> Result

Выполняется только на raft-лидере, в противном случае немедленно возвращает ошибку.

Этy хранимую процедуру вызывают инстансы Picodata, присоединяющиеся к кластеру, то есть еще не состоящие в raft-группе.

См. также:

Параметры:

  • cluster_name: (MP_STR)
  • instance_name: (MP_STR | MP_NIL)
  • replicaset_name: (MP_STR | MP_NIL) идентификатор репликасета
  • advertise_address: (MP_STR)
  • failure_domain: (MP_MAP) домен отказа
  • tier: (MP_STR) идентификатор тира

Возвращаемое значение:

  • (MP_MAP Response):
    • instance: (MP_MAP): кортеж из системной таблицы _pico_instance, соответствующий присоединяющемуся инстансу
    • peer_addresses: (MP_ARRAY): набор адресов некоторых инстансов кластера
      • (MP_MAP PeerAddress):
        • raft_id: (MP_INT)
        • address: (MP_STR)
    • box_replication: (MP_ARRAY of MP_STR): адреса всех реплик в репликасете присоединяющегося инстанса

.proc_raft_promote

fn proc_raft_promote()

Завершает текущий raft-терм и объявляет выборы нового лидера. Предлагает себя как кандидата в лидеры raft-группы. Если других кандидатов не обнаружится, текущий инстанс с большой вероятностью станет новым лидером.

.proc_raft_snapshot_next_chunk

fn proc_raft_snapshot_next_chunk(entry_id, position) -> Result

Возвращает следующий отрезок данных raft-снапшота.

Этy хранимую процедуру вызывают только инстансы с ролью raft follower в рамках процесса актуализации raft-журнала.

Текущий инстанс проверяет наличие снапшота соответствующего состоянию raft-журнала на момент, когда актуальными были указанные терм и индекс. При этом, снапшот должен существовать на момент вызова этой процедуры, так как он создается автоматически когда raft-лидер получает запрос на актуализацию raft-журнала и обнаруживает, что его журнал был компактизирован.

Снапшот представляет из себя последовательность кортежей глобальных таблиц, как системных так и пользовательских. В этой последовательности кортежи сгруппированы по таблицам и упорядочены в соответствие с первичными ключами таблиц. Последовательность таблиц в снапшоте детерминирована и совпадает между разными версиями снапшотов.

Следующий отрезок снапшота определяется параметрами: идентификатором последней таблицы, кортежи которой были получены в предыдущем отрезке, и количеством кортежей этой таблицы, полученных за все предыдущие отрезки снапшота.

Параметры:

  • entry_id (MP_MAP RaftEntryId):
    • index: (MP_INT)
    • term: (MP_INT)
  • position: (MP_MAP SnapshotPosition)
    • space_id: (MP_INT)
    • tuple_offset: (MP_INT)

Возвращаемое значение:

  • snapshot_data (MP_MAP SnapshotData):
    • schema_version: (MP_INT)
    • space_dumps: (MP_ARRAY):
      • (MP_MAP SpaceDump):
        • space_id: (MP_INT)
        • tuples: (MP_ARRAY of MP_ARRAY) «сырые» кортежи таблицы
    • next_chunk_position: (MP_MAP SnapshotPosition | MP_NIL)

.proc_read_index

fn proc_read_index(timeout) -> RaftIndex

Выполняет кворумное чтение по следующему принципу:

  1. Инстанс направляет запрос (MsgReadIndex) лидеру raft-группы. В случае, если лидера в данный момент нет, функция возвращает ошибку 'raft: proposal dropped'
  2. Raft-лидер запоминает текущий commit_index и отправляет всем узлам в статусе follower сообщение (heartbeat) с тем, чтобы убедиться, что он все еще является лидером
  3. Как только получение этого сообщения подтверждается большинством follower-узлов, лидер возвращает этот индекс инстансу
  4. Инстанс дожидается применения (apply) указанного raft-индекса. Если таймаут истекает раньше, функция возвращает ошибку 'timeout'

Параметры:

  • timeout: (MP_INT | MP_FLOAT) в секундах

Возвращаемое значение:

  • (MP_INT RaftIndex)

.proc_replication

fn proc_replication(is_master, replicaset_peers)

Обновляет конфигурацию топологии репликации текущего инстанса с остальными инстансами из одного репликасета.

Данную хранимую процедуру вызывает только governor в рамках алгоритма автоматической смены топологии кластера.

Первоисточником принадлежности инстанса к тому или иному репликасету является информация в системной таблице _pico_instance, однако при вызове этой хранимой процедуры список адресов инстансов указывается явно из-за ограничений на репликацию системных таблиц: так как данные системных таблиц распространяются через механизм репликации, его нужно настроить перед тем, как данные смогут реплицироваться.

Для репликации Picodata использует топологию full-mesh, при которой каждая реплика поддерживает соединение с каждой другой репликой. При этом, мастер-реплика в каждом репликасете только одна. Признак того, что текущая реплика должна стать мастером, передается соответствующим параметром.

См. также:

Параметры:

  • is_master: (MP_BOOL)
  • replicaset_peers: (MP_ARRAY of MP_STR)

.proc_replication_demote

fn proc_replication_demote() -> Vclock

Переводит текущий инстанс в состояние резервной реплики.

Данную хранимую процедуру вызывает только governor в рамках алгоритма автоматической смены текущего мастера репликасета.

См. также:

Получив такой запрос, инстанс сразу переходит в режим read-only и отправляет в ответ текущее значение своего Vclock, которое дальше используется для синхронизации новой мастер-реплики.

См. .proc_replication о том, как в Picodata настраивается репликация.

Возвращаемое значение:

  • vclock: (MP_MAP Vclock)

.proc_replication_sync

fn proc_replication_sync(vclock, timeout)

Обеспечивает репликацию Tarantool для текущего инстанса, пока значение его Vclock не станет равным vclock.

Параметры:

  • vclock: (MP_MAP Vclock)
  • timeout: (MP_INT | MP_FLOAT) в секундах

.proc_runtime_info

fn proc_runtime_info() -> RuntimeInfo

Возвращает служебную информацию.

Возвращаемое значение:

  • (MP_MAP RuntimeInfo):
    • raft: (MP_MAP RaftInfo)
    • internal: (MP_MAP InternalInfo)
      формат: MP_MAP { main_loop_status = MP_STR, governor_loop_status = MP_STR, governor_step_counter = MP_INT }
    • http: (optional MP_MAP HttpServerInfo)
      формат: MP_MAP { host = MP_STR, port = MP_UINT }
      поле отсутствует в ответе, если инстанс запущен без параметра picodata run --http-listen
    • version_info: (MP_MAP VersionInfo)
    • slab_info: (MP_MAP SlabInfo)

.proc_sharding

fn proc_sharding(term, applied, timeout)

Дожидается применения raft-записи с заданным индексом и термом перед тем как делать что-то еще, чтобы синхронизовать состояние глобальных системных таблиц. Возвращает ошибку, если времени не хватило.

Обновляет конфигурацию шардирования данных между репликасетами.

Этy хранимую процедуру вызывает только governor в рамках алгоритма автоматической смены топологии кластера.

См. также:

В системной таблице _pico_tier хранятся две версии конфигурации распределения бакетов: текущая и целевая (target). Этим версиям соответствуют колонки current_vshard_config_version и target_vshard_config_version.

Параметры:

  • term: (MP_INT RaftTerm)
  • applied: (MP_INT RaftIndex)
  • timeout: (MP_INT | MP_FLOAT) в секундах

.proc_sharding_bootstrap

fn proc_sharding_bootstrap(term, applied, timeout, tier)

Дожидается применения raft-записи с заданным индексом и термом перед тем как делать что-то еще, чтобы синхронизовать состояние глобальных системных таблиц. Возвращает ошибку, если времени не хватило.

Инициирует распределение бакетов между репликасетами.

Этy хранимую процедуру вызывает только governor в рамках алгоритма автоматической смены топологии кластера.

См. также:

За жизненный цикл кластера эта процедура вызывается ровно один раз, как только в кластере появляется первый репликасет, удовлетворяющий соответствующему фактору репликации.

Параметры:

  • term: (MP_INT RaftTerm)
  • applied: (MP_INT RaftIndex)
  • timeout: (MP_INT | MP_FLOAT) в секундах
  • tier: (MP_STR)

.proc_sql_execute

fn proc_sql_execute(..) -> Result

Выполняет часть плана SQL-запроса на локальном инстансе.

Аргументы:

  • Сериализованный план запроса

Возвращаемое значение:

  • (MP_MAP DqlResult) при чтении данных
    Поля:
    • metadata (MP_ARRAY), массив описаний столбцов таблицы в формате MP_ARRAY [ MP_MAP { name = MP_STR, type = MP_STR }, ...]
    • rows (MP_ARRAY), результат выполнения читающего запроса в формате MP_ARRAY [ MP_ARRAY row, ...]
  • (MP_MAP DmlResult) при модификации данных
    Поля:
    • row_count (MP_INT), количество измененных строк

Для более высокоуровневого RPC смотрите .proc_sql_dispatch

.proc_update_instance

fn proc_update_instance(instance_name, cluster_name, current_state, target_state, failure_domain, dont_retry)

Выполняется только на raft-лидере, в противном случае немедленно возвращает ошибку.

Обновляет информацию об указанном инстансе.

Этy хранимую процедуру вызывают инстансы Picodata, уже состоящие в кластере, чтобы обновить свое целевое состояние при перезапуске или в рамках штатного выключения.

Лидер, получив такой запрос, проверяет консистентность параметров (например, что новый домен отказа не противоречит конфигурации репликасета), и выполняет CaS-операцию по применению изменений к глобальной системной таблице _pico_instance.

По умолчанию, если в raft-журнал попала конфликтующая CaS-операция, запрос повторяется.

Параметры:

  • instance_name: (MP_STR)
  • cluster_name: (MP_STR)
  • current_state: (MP_MAP State | MP_NIL), текущее состояние инстанса
  • target_state: (MP_STR StateVariant | MP_NIL), целевое состояние инстанса
  • failure_domain: (MP_MAP | MP_NIL) домен отказа
  • dont_retry: (MP_BOOL), не повторять CaS запрос в случае конфликта

.proc_wait_bucket_count

fn proc_wait_bucket_count(term, applied, timeout, expected_bucket_count)

Обеспечивает перенос бакетов из исключаемого репликасета, пока число бакетов в репликасете не станет равным нулю.

Параметры:

  • term: (MP_INT)
  • applied: (MP_INT)
  • timeout: (MP_INT | MP_FLOAT) в секундах
  • expected_bucket_count: (MP_INT)

.proc_wait_index

fn proc_wait_index(target, timeout) -> RaftIndex

Ожидает применения (apply) указанного raft-индекса на текущем инстансе. Функция возвращает текущий примененный индекс raft-журнала, который может быть равен или превышать указанный.

Параметры:

  • target: (MP_INT)
  • timeout: (MP_INT | MP_FLOAT) в секундах

Возвращаемое значение:

  • (MP_INT RaftIndex)

.proc_wait_vclock

fn proc_wait_vclock(target, timeout) -> Vclock

Ожидает момента, когда текущее значение Vclock достигнет заданного. Возвращает текущее значение Vclock, которое может быть равно или превышать указанное.

Параметры:

  • target: (MP_MAP Vclock)
  • timeout: (MP_FLOAT) в секундах

Возвращаемое значение:

  • (MP_MAP Vclock)