TDB Documentation portal logo
Помощь
Обновлена 22 октября 2026 г. в 11:37

Модуль crud

Модуль crud предоставляет методы для выполнения CRUD-операций в шардированном кластере Tarantool DB.

Модуль crud:

  • вычисляет bucket_id и маршрутизирует запрос на нужный набор реплик;
  • выполняет операции на экземплярах хранилища через net.box;
  • выдаёт результат в формате (rows + metadata) для операций, возвращающих кортежи. Остальные методы могут возвращать значения других типов. Подробную информацию об этом можно найти в описании конкретного метода.

Узнать больше о модуле CRUD можно в репозитории tarantool/crud.

Подробнее о технологических ролях roles.crud-router и roles.crud-storage можно узнать в разделе Технологические роли.

Общая информация о модуле

В TDB основной способ работы с данными кластера — CRUD-операции (crud.*). CRUD предоставляет единый интерфейс чтения и записи по всему кластеру (clusterwide) и берёт на себя маршрутизацию запросов.

Нативные операции Tarantool (box.space.*: insert, replace, update, delete, select) — это низкоуровневый API для работы со спейсом на уровне набора реплик. Они выполняются локально на конкретном узле хранилища и предназначены в первую очередь для реализации хранимых процедур и локальных транзакций.

Формат результатов и преобразование в объекты

Операции, которые возвращают кортежи (например, select, get, insert, replace, update), возвращают таблицу со следующими полями:

  • rows — массив кортежей;
  • metadata — формат space (описание полей).

Остальные методы могут возвращать значения других типов, например number или boolean. Подробнее см. в описании конкретного метода.

Пример:

local res, err = crud.select('customers', nil, { first = 2 })-- res.metadata + res.rows

Пример структуры ответа:

metadata:  - {name: id, type: unsigned}  - {name: bucket_id, type: unsigned}  - {name: name, type: string}  - {name: age, type: number}rows:  - [1, 12477, "Elizabeth", 12]  - [2, 21401, "David", 33]

Чтобы преобразовать rows в массив объектов (таблиц с именованными полями):

local objects = crud.unflatten_rows(res.rows, res.metadata)

Шардирование

Ниже приведены основные термины, связанные с шардированием.

  • Ключ шардирования (sharding key) — набор значений полей кортежа, по которым вычисляется bucket_id.
  • Определение ключа шардирования (sharding key definition) — список имен полей, входящих в ключ шардирования.
  • Функция шардирования (sharding function) — функция, вычисляющая bucket_id по ключу шардирования.
  • bucket_id определяет, на каком наборе реплик хранится кортеж.

По умолчанию CRUD:

  • использует первичный ключ (primary key) в качестве ключа шардирования;
  • автоматически вычисляет bucket_id.

Для операций, принимающих кортеж или объект, bucket_id можно указать двумя способами:

  • как поле в кортеже или объекте,
  • через поле opts.bucket_id.

Запросы по первичному ключу без явного bucket_id

Если шардирующий индекс, в котором bucket_id — первое поле, одновременно является первичным индексом (primary index), CRUD может автоматически подставить bucket_id.

Передайте box.NULL вместо первой части ключа:

crud.get('customers', { box.NULL, customer_id })crud.update('customers', { box.NULL, customer_id }, {{'=', 'name', 'Jane'}})crud.delete('customers', { box.NULL, customer_id })

Условия:

  • у роутера актуальные метаданные шардирования;
  • первичный индекс имеет вид (bucket_id, ...).

Пользовательский ключ шардирования и функция шардирования (DDL)

При необходимости вместо первичного ключа можно использовать отдельный ключ шардирования. Его можно задать:

  • в DDL-схеме;
  • вручную, добавив запись в таблицу _ddl_sharding_key.

После появления кортежа в спейсе _ddl_sharding_key модуль CRUD начнет автоматически использовать указанный ключ шардирования.

Функцию, по которой вычисляется номер bucket_id, можно задать двумя способами:

  • в DDL-схеме;
  • вручную, добавив запись в таблицу _ddl_sharding_func.

Пользовательский ключ шардирования поддерживают следующие методы:

  • get()
  • insert() и insert_object()
  • delete()
  • replace() и replace_object()
  • upsert() и upsert_object()
  • select() и pairs()
  • count()
  • update()

Пользовательский ключ шардирования не требуется и не поддерживается в следующих методах:

  • min() и max()
  • cut_rows() и cut_objects()
  • truncate()
  • len()

Ограничения strcrc32

По умолчанию CRUD использует strcrc32. Эта функция работает непоследовательно для чисел типа cdata и может возвращать разные значения для:

  • обычного числа Lua (123)
  • 123ULL (ffi.cast('unsigned long long', 123))
  • 123LL (ffi.cast('long long', 123))

Из-за обратной совместимости значение по умолчанию не меняют, но рекомендуется рассмотреть альтернативы (например, mpcrc32) через механизм задания функции шардирования (sharding function).

Параметры маршрутизации и выполнения запроса для CRUD-методов

Читающие CRUD-методы (например, get, select, count, min, max, pairs) могут выполняться либо на мастер-узле, либо на репликах.

Для управления маршрутизацией эти методы имеют дополнительные опции:

  • mode (тип: string) — Режим маршрутизации:

    • 'write' - направлять запрос всегда на мастер, в этом случае другие опции не учитываются;
    • 'read' - учитываются остальные опции.
  • prefer_replica (тип: bool) — Если true - при недоступности реплик запрос перенаправляется на мастер.

  • balance (тип: bool) — Балансировка нагрузки:

    • false - запрос направляется на первую доступную реплику из списка;
    • true - запрос направляется на все узлы по кругу.

Сочетание значений даёт такой эффект:

mode

prefer_replica

balance

Куда роутер отправит запрос

write

не важно

не важно

На мастер-узел

read

false

false

На первую доступную реплику из списка

read

false

true

На реплики по кругу (round-robin)

read

true

false

На первую доступную реплику, и если их нет, то на мастер-узел

read

true

true

На реплики по кругу (round-robin), и если они недоступны, то на мастер-узел

Справочник

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

crud.atomic_batch(operations[, opts])

Доступно с версии TDB 3.3.0 и crud 1.8.0.

Выполнить упорядоченный список (пакет) простых CRUD-операций над разными спейсами в одной транзакции в одном сегменте (с одинаковым bucket_id). Если хотя бы одна операция завершается ошибкой, вся транзакция откатывается, и данные остаются в исходном состоянии. Пакет с разными значениями bucket_id отклоняется на этапе проверки на роутере. Отследить работу метода можно по метрикам tnt_crud_atomic_batch_sub_ops* и tnt_crud_stats_* (с указанием типа операции operation = "atomic_batch"). Узнать больше: Метрики метода crud.atomic_batch().

Ограничения:

  • Все операции в пакете должны иметь одинаковый bucket_id. Наличие операций с разными bucket_id вызывает ошибку валидации на этапе роутера — до отправки сетевого запроса на хранилище, даже если эти bucket_id относятся к одному набору реплик;
  • Метод поддерживает только операции записи (insert, replace, update, upsert, delete) и точечную операцию чтения get. Массовые операции чтения (select, pairs, count) не поддерживаются.
  • Сочетание спейсов на движках memtx и vinyl в одном пакете требует обязательного включения MVCC. Если в транзакции используются только спейсы vinyl, работа допустима при выключенном MVCC.

Параметры:

  • operations — упорядоченный массив операций. Тип: table. Каждый элемент массива — таблица, которая описывает одну операцию. Для всех операций обязательны поля type и space, остальные поля зависят от типа операции. Поддерживаемые поля:

    • type — тип операции. Обязательный параметр;

    • space — имя спейса. Обязательный параметр;

    • key — значение первичного ключа. Обязательный параметр для операций get, update, delete. Не используется для других типов операций;

    • tuple или object — кортеж или объект соответственно. Использование одного из этих параметров обязательно для операций insert, replace, upsert. Не применяются для других типов операций.

    • operations — массив update-операций. Обязательный параметр для операций update и upsert. Не используется для других типов операций;

  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:

    • timeout — время ожидания на выполнение всего пакета в секундах. Тип: number. Значение по умолчанию: 2;

    • noreturn — если true, не возвращает результаты операций в ответе (для оптимизации трафика). Тип: boolean. По умолчанию: false;

    • fields — проекция полей для возвращаемых результатов, задаётся с агрегацией по спейсам. Тип: table. Параметр задаётся как словарь, где ключ — это имя спейса, а значение — список имён полей:

      opts = {    fields = {        users = {"id", "name"},        orders = {"id", "status"},    },}

Возвращает:

  • result — таблица со следующими полями:

    • metadata — словарь метаданных по именам используемых спейсов;
    • ops — список дескрипторов {type, space} для каждой операции, выровненный с data;
    • data — упорядоченный список результатов операций.

    Если opts.noreturn = true, то метод возвращает nil вместо таблицы с результатом;

  • err — nil (в случае успеха) или ошибка. При ошибке возвращается таблица с полями:

    • class_name — класс ошибки;
    • err — полное сообщение ошибки;
    • operation_index — номер неудачной операции в пакете;
    • operation_data — дескриптор неудачной операции: type, space и кортеж tuple. Если операция задана через object, он уже приведён к кортежу.

Пример:

local crud = require('crud')-- Спейс users шардируется по полю id, спейсы orders и audit_log по полю user_id.-- Все операции ниже относятся к пользователю 42, поэтому их bucket_id совпадает.local operations = {    -- 1. Чтение профиля пользователя    { type = 'get', space = 'users', key = { 42 } },    -- 2. Создание заказа через поле tuple    { type = 'insert', space = 'orders', tuple = { 10001, box.NULL, 42, 'created', 1500 } },    -- 3. Запись события в аудит-лог через поле object    { type = 'insert', space = 'audit_log', object = {        id = 5001, user_id = 42, order_id = 10001, event = 'ORDER_CREATED', created_at = os.time()    } },}local res, err = crud.atomic_batch(operations, {    timeout = 1.5,    fields = {        users = { 'id', 'name' },        orders = { 'id', 'status' },        audit_log = { 'id', 'event' },    },})--[[res = {    metadata = {        users = {            { name = 'id', type = 'unsigned' },            { name = 'name', type = 'string' }        },        orders = {            { name = 'id', type = 'unsigned' },            { name = 'status', type = 'string' }        },        audit_log = {            { name = 'id', type = 'unsigned' },            { name = 'event', type = 'string' }        }    },    ops = {        [1] = { type = 'get', space = 'users' },        [2] = { type = 'insert', space = 'orders' },        [3] = { type = 'insert', space = 'audit_log' }    },    data = {        [1] = { 42, 'Alex' },        [2] = { 10001, 'created' },        [3] = { 5001, 'ORDER_CREATED' }    }}--]]

crud.insert(space_name, tuple[, opts])

Вставить кортеж в указанный спейс шардированного кластера. Вызов выполняется на роутере, фактическая вставка кортежа происходит на нужном экземпляре хранилища по bucket_id.

Параметры:

  • space_name — название спейса. Тип: string;
  • tuple — вставляемый кортеж (массив значений в порядке формата спейса). Тип: table;
  • opts – дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • noreturn — если true, не возвращает обработанный кортеж (первый результат будет nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — при успехе таблицу с:
    • metadata — метаданными в формате space;
    • rows — массив из одной вставленной строки (tuple). Если opts.noreturn = true, то result == nil;
  • err — ошибку или nil.

Пример:

local res, err = crud.insert('customers', {1, box.NULL, 'Elizabeth', 23})-- res.rows[1] содержит вставленный кортеж, bucket_id может быть вычислен автоматически

crud.insert_object(space_name, object[, opts])

Вставить объект в указанный спейс. Объект — это таблица вида {field_name = value, ...}.

Параметры:

  • space_name — название спейса. Тип: string;
  • object — вставляемый объект (ключи — имена полей). Тип: table;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • skip_nullability_check_on_flatten — только для insert_object. Тип: boolean. По умолчанию: false. Если true, разрешает передавать null в поля, объявленные как is_nullable = false. Используется, например, когда значение non-nullable поля генерируется на стороне БД (условно “sequence”); В шардированных системах нет встроенной поддержки последовательностей (sequences), поскольку у каждого набора реплик своя собственная последовательность. Если поле с последовательностью входит в ключ шардирования (по умолчанию так и есть), выбор bucket_id полностью лежит на разработчике;
    • noreturn — если true, не возвращает обработанный кортеж (первый результат будет nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — при успехе таблицу с:
    • metadata — метаданными в формате space;
    • rows — массив из одной вставленной строки (tuple). Если opts.noreturn = true, то result == nil;
  • err — ошибку или nil.

Пример:

local res, err = crud.insert_object('customers', {  id = 2,  name = 'Elizabeth',  age = 24,})

crud.get(space_name, key[, opts])

Вернуть один кортеж по первичному ключу из указанного спейса.

По умолчанию выполняется в режиме чтения (mode = 'read') и может быть направлен на реплику (в зависимости от настроек prefer_replica и balance). Если нужен гарантированный запрос на мастер-узле — используйте mode = 'write'.

Параметры:

  • space_name — название спейса. Тип: string;
  • key — значение первичного ключа в том виде, как ожидает индекс: скаляр или составной ключ таблицей. Тип: any;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • fields — имена полей для получения подмножества полей. Тип: table;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем;
    • mode — режим доступа. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: read;
    • prefer_replica — если задано значение true, предпочитаемой целью для выполнения запроса на выборку будет один из экземпляров реплики. Тип: boolean;
    • balance — если задано значение true, включена балансировка нагрузки. Тип: boolean;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — при успехе таблицу с:
    • metadata — метаданными в формате space;
    • rows — массив из одной строки или пустой массив, если кортеж не найден;
  • err — ошибку или nil.

Пример:

local res, err = crud.get('customers', 1)-- res.rows[1] == [1, 477, 'Elizabeth', 23]

crud.update(space_name, key, operations[, opts])

Обновить один кортеж по первичному ключу, применяя список update-операций (аналогично box.space:update по смыслу операций).

Параметры:

  • space_name — название спейса. Тип: string;
  • key — значение первичного ключа. Тип: any;
  • operations — массив операций обновления. Тип: table Пример: {{'+', 'age', 1}} (увеличить поле age на 1);
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • noreturn — если true, не возвращает обновленную строку (result == nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — таблицу с metadata + rows (одна обновленная строка) или nil при noreturn;
  • err — ошибку или nil.

Пример:

local res, err = crud.update('customers', 1, {{'+', 'age', 1}})-- age увеличится на 1

crud.delete(space_name, key[, opts])

Удалить один кортеж по первичному ключу.

Параметры:

  • space_name — название спейса. Тип: string;
  • key — значение первичного ключа. Тип: any;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • noreturn — если true, не возвращает удаленную строку (result == nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — таблицу с metadata + rows (поле rows содержит одну удалённую строку, а для vinyl остаётся пустым) или nil при noreturn;
  • err — ошибку или nil.

Пример:

local res, err = crud.delete('customers', 1)

crud.replace(space_name, tuple[, opts])

Вставить кортеж, а если кортеж с таким первичным ключом уже существует — заменяет его целиком.

Параметры:

  • space_name — название спейса. Тип: string;
  • tuple — кортеж для вставки или замены. Тип: table;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • noreturn — если true, не возвращает строку (result == nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — таблицу с metadata + rows (одна вставленная или замененная строка) или nil при noreturn;
  • err — ошибка или nil.

Пример:

local res, err = crud.replace('customers', {1, box.NULL, 'Alice', 22})

crud.replace_object(space_name, object[, opts])

Заменить кортеж в спейсе по первичному ключу: если кортеж уже существует — перезаписывает его целиком, если нет — вставляет новый. Принимает данные в виде объекта {field = value, ...}.

Параметры:

  • space_name — название спейса. Тип: string;
  • object — объект для вставки или замены. Тип: table;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • skip_nullability_check_on_flatten — только для replace_object. Тип: boolean. По умолчанию false. Если true, разрешает передавать null в поля, объявленные как is_nullable = false; Используется, например, когда значение non-nullable поля генерируется на стороне БД (условно “sequence”); В шардированных системах нет встроенной поддержки последовательностей (sequences), поскольку у каждого набора реплик своя собственная последовательность. Если поле с последовательностью входит в ключ шардирования (по умолчанию так и есть), выбор bucket_id полностью лежит на разработчике;
    • noreturn — если true, не возвращает строку (result == nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — таблицу с metadata + rows (одна строка) или nil при noreturn;
  • err — ошибку или nil.

Пример:

local res, err = crud.replace_object('customers', {  id = 1,  name = 'Alice',  age = 22,})

crud.upsert(space_name, tuple, operations[, opts])

Выполнить UPSERT (вставка или обновление) для кортежа:

  • если записи с ключом из tuple нет — вставляет кортеж;
  • если кортеж есть — применяет операции обновления к существующему кортежу.

Параметры:

  • space_name — название спейса. Тип: string;
  • tuple — кортеж для вставки, если записи не существует. Тип: table;
  • operations — update-операции, которые применяются, если кортеж существует. Тип: table;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • noreturn — если true, подавляет успешный результат (result == nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — при успехе таблицу:
    • metadata — метаданные в формате спейса;
    • rows — пустой массив []. Если opts.noreturn = true, то result == nil;
  • err — ошибку или nil.

Пример:

local res, err = crud.upsert('customers',    {1, box.NULL, 'Alice', 22},    {{'+', 'age', 1}})-- res.rows == {}

crud.upsert_object(space_name, object, operations[, opts])

Выполнить UPSERT (вставка или обновление) для объекта:

  • если записи с ключом из объекта нет — вставляет новый кортеж;
  • если кортеж есть — применяет операции обновления к существующему кортежу.

Метод принимает данные в виде объекта (таблицы с именованными полями) {field = value, ...}.

Параметры:

  • space_name — название спейса. Тип: string;
  • object — объект для вставки, если записи не существует. Тип: table;
  • operations — update-операции для существующей записи. Тип: table;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • noreturn — если true, метод не возвращает результат при успешном выполнении (result == nil). Тип: boolean. По умолчанию: false;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — при успехе таблицу с:
    • metadata — формат спейса;
    • rows — пустой массив []. Если opts.noreturn = true, то result == nil;
  • err — ошибка или nil.

Пример:

local res, err = crud.upsert_object('customers',    {id = 1, name = 'Alice', age = 22},    {{'+', 'age', 1}})-- res.rows == {}

crud.select(space_name[, conditions, opts])

Модуль CRUD поддерживает запросы на выборку (SELECT) с множественными условиями, кластер при этом рассматривается как единый спейс. Условия могут содержать имена полей и имена индексов. В качестве первого условия рекомендуется TREE-индекс, он позволяет уменьшить число сканируемых кортежей и не выполнять полное сканирование.

Параметры:

  • space_name — название спейса. Тип: string;
  • conditions — массив условий для выборки. Тип: table|nil;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • first — максимальное количество возвращаемых элементов. Тип: number. Если значение отрицательное, возвращаются элементы, предшествующие кортежу after. В этом случае параметр after обязателен;
    • after — кортеж, относительно которого продолжается выборка. Тип: table. При прямой пагинации в after передают последний кортеж предыдущей страницы, при обратной — первый кортеж текущей страницы;
    • batch_size — сколько кортежей обрабатывать за один запрос к экземпляру хранилища. Тип: number;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • force_map_call — если задано значение true, вызов map выполняется без оптимизаций, даже если указано полное условие равенства первичного ключа. Тип: boolean;
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • fullscan — если задано значение true, критическая запись в журнале будет пропущена при потенциально длительном select. Тип: boolean;
    • mode — режим доступа. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: read;
    • prefer_replica — если задано значение true, предпочитаемой целью для выполнения запроса на выборку будет один из экземпляров реплики. Тип: boolean;
    • balance — если задано значение true, включена балансировка нагрузки. Тип: boolean;
    • yield_every — количество кортежей, обрабатываемых в хранилище для выполнения yield после завершения обработки. Тип: number. Значение опции должно быть больше 0. Значение по умолчанию: 1000;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result — таблицу metadata + rows;
  • err — ошибку или nil.

Условия crud.select()

Каждое условие — таблица вида:

{operator, field_identifier, value}
  • operator: = (или ==), >, >=, <, <=;
  • field_identifier: имя поля или индекса.

Пример:

local res, err = crud.select('customers', {{'<=', 'age', 35}}, { first = 10 })

Кортежи отсортированы по полю age, потому что в спейсе есть индекс age. В противном случае кортежи сортируются по первичному ключу.

crud.pairs(space_name[, conditions, opts])

Итератор для обхода записей в распределенном спейсе (clusterwide), аналогично crud.select(), но в виде потока (Lua iterator). Используется, когда нужно обработать много данных без явного накопления всего результата в памяти.

Параметры:

  • space_name — название спейса. Тип: string;
  • conditions — массив условий для выборки. Тип: table|nil;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • first — максимальное количество возвращаемых элементов. Тип: number. Не поддерживает отрицательные значения;
    • after — кортеж, после которого продолжается обход записей. Тип: table. Обычно передают последний кортеж предыдущей выборки;
    • batch_size — сколько кортежей обрабатывать за один запрос к экземпляру хранилища. Тип: number;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • force_map_call — если задано значение true, вызов map выполняется без оптимизаций, даже если указано полное условие равенства первичного ключа. Тип: boolean;
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • mode — режим доступа. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: read;
    • prefer_replica — если задано значение true, предпочитаемой целью для выполнения запроса на выборку будет один из экземпляров реплики. Тип: boolean;
    • balance — если задано значение true, включена балансировка нагрузки. Тип: boolean;
    • yield_every — количество кортежей, обрабатываемых в хранилище для выполнения yield после завершения обработки. Тип: number. Значение опции должно быть больше 0. Значение по умолчанию: 1000;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.
    • use_tomap — если задано значение true, итератор возвращает объекты (таблицы с именованными полями) вместо кортежей. Тип: boolean. Значение по умолчанию: false.

Возвращает:

Метод crud.pairs() возвращает итератор. В цикле for вы получаете:

  • при use_tomap = false: tuple (table-массив)
  • при use_tomap = true: object (table-map)

Примеры:

  • итерация по кортежам (tuples):

    local tuples = {}for _, tuple in crud.pairs('customers', {{'<=', 'age', 35}}, { use_tomap = false }) do    -- пример tuple: {5, 1172, 'Jack', 35}    table.insert(tuples, tuple)end
  • итерация по таблицам с именованными полями (objects):

    local objects = {}for _, object in crud.pairs('customers', {{'<=', 'age', 35}}, { use_tomap = true }) do-- пример object: {id = 5, name = 'Jack', bucket_id = 1172, age = 35}table.insert(objects, object)end

crud.min(space_name[, index_id, opts])

Вернуть минимальный кортеж по указанному индексу в распределенном спейсе.

Параметры:

  • space_name — название спейса. Тип: string;
  • index_id — имя или идентификатор индекса. Тип: string|number. По умолчанию — primary index;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • mode — режим доступа. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: read;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result (table) — metadata + rows (одна строка);
  • err — ошибку или nil.

Пример:

local res, err = crud.min('customers', 'age')-- res.rows[1] == [1, 477, 'Elizabeth', 12]

crud.max(space_name[, index_id, opts])

Вернуть максимальный кортеж по указанному индексу в распределенном спейсе.

Параметры:

  • space_name — название спейса. Тип: string;
  • index_id — имя или идентификатор индекса. Тип: string|number. По умолчанию — primary index;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем;
    • fields — имена полей для получения подмножества полей. Тип: table;
    • mode — режим доступа. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: read;
    • fetch_latest_metadata — если задано значение true, опция гарантирует актуальность метаданных (формат спейса) в первом возвращаемом значении. Если указано значение false, опция может не учитывать последнюю миграцию формата данных. Тип: boolean. Значение по умолчанию: false.

Возвращает:

  • result (table) — metadata + rows (одна строка);
  • err — ошибку или nil.

Пример:

local res, err = crud.max('customers', 'age')-- res.rows[1] == [5, 1172, 'Jack', 35]

crud.cut_rows(rows, metadata, fields)

Метод cut_rows() используется после crud.select() или crud.pairs() в режиме частичного возврата полей (opts.fields), чтобы убрать «служебные» значения ключа сканирования и первичного ключа, которые CRUD мог добавить в результат. В результате rows содержит больше полей, чем ожидается по fields. Метод cut_rows() удаляет эти добавленные значения и приводит результат к виду «ровно те поля, которые были запрошены».

Параметры:

  • rows — массив кортежей, которые необходимо «обрезать». Тип: table;
  • metadata — метаданные (формат) для rows. Тип: table|nil;
  • fields — список имен полей, которые должны остаться в результате. Тип: table.

Возвращает:

  • res — таблицу с:
    • metadata — метаданными уже «обрезанного» результата,
    • rows — массив кортежей, содержащих только поля из fields.
  • err — ошибку или nil.

Примеры: select(fields=...) + cut_rows() + пагинация (after). Если по какой-то причине необходимы кортежи, то самый стабильный способ — select() с пагинацией. У select() есть метаданные, поэтому cut_rows() применяется корректно:

local crud = require('crud')local fields = {'id', 'name'}local after = nilwhile true do    local res, err = crud.select('customers', {{'<=', 'age', 35}}, {        fields = fields,        first = 100,   -- размер страницы        after = after,    })    if err ~= nil then        error(err)    end    if res.rows == nil or #res.rows == 0 then        break    end    -- для пагинации after должен быть кортежем из исходного res.rows (до cut_rows)    after = res.rows[#res.rows]    -- убрать служебные части ключей, оставить только id и name    local cut_res, cut_err = crud.cut_rows(res.rows, res.metadata, fields)    if cut_err ~= nil then        error(cut_err)    end    for _, tuple in ipairs(cut_res.rows) do        local id = tuple[1]        local name = tuple[2]        print(id, name)    endend

Использовать когда:

  • нужна контролируемая пагинация;
  • необходима работа с кортежами и метаданными;
  • важна предсказуемость курсора after.

crud.cut_objects(objects, fields)

Удалить из объектов лишние поля, которые CRUD мог добавить в результаты pairs() при выборке с opts.fields. Актуально, когда crud.pairs() используется с use_tomap = true (возвращаются objects), и для корректной распределенной итерации в результат были добавлены значения ключа сканирования по индексу или первичного ключа.

Параметры:

  • objects — массив объектов (таблиц с именованными полями), которые нужно привести к запрошенному набору полей. Тип: table;
  • fields — список имен полей, которые должны остаться в результате (как в opts.fields). Тип: table.

Возвращает:

  • new_objects — массив объектов, содержащих только поля из fields. Тип: table.

Пример:

local fields = {'id', 'name'}local objects = {}for _, obj in crud.pairs('customers', nil, {use_tomap = true, fields = fields}) do    table.insert(objects, obj)end-- Убрать «технические» поля, добавленные для распределенной итерацииlocal new_objects = crud.cut_objects(objects, fields)

crud.truncate(space_name[, opts])

Полностью очистить спейс во всем кластере (распределенная очистка).

Параметры:

  • space_name — название спейса. Тип: string;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number.

Возвращает:

  • ok — true при успехе, иначе nil. Тип: boolean|nil.
  • err — ошибка или nil.

Пример:

crud.truncate('customers', { timeout = 2 })-- -> true

crud.len(space_name[, opts])

Вернуть количество кортежей в спейсе по кластеру:

  • для memtx: фактическое количество кортежей;
  • для vinyl: максимальная приблизительная оценка количества кортежей.

Параметры:

  • space_name — название спейса. Тип: string;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number;
    • mode — режим доступа. Параметр доступен с версий TDB 3.2.0 и CRUD 1.7.5. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: write;
    • balance — если задано значение true, включена балансировка нагрузки. Параметр доступен с версий TDB 3.2.0 и CRUD 1.7.5. Тип: boolean;
    • prefer_replica — если задано значение true, предпочитаемой целью для выполнения запроса на выборку будет один из экземпляров реплики. Опция доступна с версий TDB 3.2.0 и CRUD 1.7.5. Тип: boolean;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Параметр доступен с версий TDB 3.2.0 и CRUD 1.7.5. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем.

Возвращает:

  • count (number|nil) — число кортежей или nil при ошибке.
  • err — ошибку или nil.

Примеры:

  • для memtx:

    local n, err = crud.len('customers', { timeout = 2 })
  • для vinyl:

    local n, err = crud.len('customers')

crud.storage_info([opts])

Вернуть статус экземпляров хранилища в кластере (диагностика доступности/инициализации).

Параметры:

  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number.

Возвращает:

  • info — таблицу по UUID узла. Для каждого экземпляра:
    • status:
      • "running" — экземпляр хранилища инициализирован и работает;
      • "uninitialized" — экземпляр хранилища не инициализирован или отключён;
      • "error" — ошибку получения статуса (например, проблемы соединения);
    • is_master — true, если экземпляр мастер;
    • message — текст проблемы, если status == "error";
  • err — ошибку или nil.

Пример:

crud.storage_info()---- fe1b5bd9-42d4-4955-816c-3aa015e0eb81:    status: running    is_master: true  a1eefe51-9869-4c4c-9676-76431b08c97a:    status: running    is_master: true  777415f4-d656-440e-8834-7124b7267b6d:    status: uninitialized    is_master: false  e1b2e202-b0f7-49cd-b0a2-6b3a584f995e:    status: error    message: 'connect, called on fd 36, aka 127.0.0.1:49762: Connection refused'    is_master: false...

crud.storage_call(func_name, args, opts)

Доступно с версии TDB 3.3.0 и crud 1.8.0.

Вызвать персистентную хранимую функцию из box.func на мастер-узле набора реплик, которому принадлежит сегмент. Хранимая функция должна выполнить ограниченную операцию над одним сегментом и вернуть её фактический результат до завершения работы метода crud.storage_call().

Функция должна соответствовать требованиям ниже:

  • функция персистентна: функция должна быть создана в box.func с сохранённым телом (body). Lua-код функции хранится в поле body системного спейса _func и восстанавливается после перезапуска Tarantool;

  • функция должна быть задана миграцией на всех хранилищах, где может находиться сегмент. Вызов не будет выполнен, если после переноса сегмента функции не будет на нужном хранилище;

  • опция setuid задана со значением setuid = false;

  • функция должна завершать собственную локальную транзакцию. Если она оставит транзакцию открытой, модуль CRUD откатит её и вернёт ошибку вызова. Уже зафиксированные изменения не откатываются;

  • хранимая функция выполняется с правами пользователя, который вызвал метод crud.storage_call(). Это означает, что этот пользователь должен иметь права на вызов этой функции (execute). На роутере требуется выдать права на вызов crud.storage_call():

    box.schema.user.grant(    'application_user',    'execute',    'lua_call',    'crud.storage_call',    {if_not_exists = true})

    На хранилище требуется выдать права на выполнение нужной хранимой функции (execute), в примере это функция app.process_handler:

    box.schema.user.grant(    'application_user',    'execute',    'function',    'app.process_handler',    {if_not_exists = true})

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

Параметры:

  • func_name — имя хранимой функции в box.func. Тип: string;

  • args — массив аргументов функции без пропусков. Тип: table. Значение по умолчанию: {};

  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:

    • bucket_id — идентификатор сегмента. Тип: number или cdata, приводимое к целому Lua-числу от 1 до количества сегментов в выбранном vshard-роутере;
    • space_name — название спейса, по первичному ключу которого вычисляется сегмент. Тип: string. Указывается вместе с параметром key, если пропущен параметр bucket_id;
    • key — значение первичного ключа спейса space_name. Тип: any — скаляр, массив частей ключа или кортеж. Указывается вместе с параметром space_name, если пропущен параметр bucket_id;
    • timeout — общее время ожидания выполнения операции в секундах (маршрутизация, отправка и ожидание ответа). Тип: number. Значение по умолчанию: 2. Истечение времени ожидания в timeout не отменяет уже запущенную функцию: она может завершиться и зафиксировать изменения после того, как клиент получил ошибку. Пока функция выполняется, заявленный ею сегмент защищён от миграции на этом хранилище;
    • vshard_router — экземпляр vshard-роутера. Тип: table.

Возвращает:

  • result — при успехе таблицу с массивом returns, иначе nil. В массиве returns сохраняются все значения, возвращённые вызванной хранимой функцией: при этом nil сохраняется как box.NULL, значение false сохраняется как есть. Второе возвращённое значение интерпретируется как данные, а не как ошибка;
  • err — ошибку или nil. Ошибка может содержать следующие поля:
    • err — описание причины;

    • func_name — имя хранимой функции;

    • bucket_id — сегмент, на который маршрутизировался вызов;

    • replicaset_id — набор реплик, на котором выполнялся вызов;

    • may_have_side_effects — могла ли функция уже изменить данные. Значение false возвращается только тогда, когда модуль CRUD точно знает, что целевая функция не запускалась (например, после проверки аргументов, при отсутствии функции или её неперсистентной регистрации, либо при отклонённых метаданных маршрутизации). Исключения при вызове целевой функции, включая ошибки доступа, помечаются значением true, поскольку ошибка могла возникнуть во вложенном вызове уже после фиксации изменений.

      Модуль crud не повторяет автоматически попытку выполнения хранимой функции, повтор вызова с may_have_side_effects = true безопасен только для идемпотентной функции.

Примеры:

Предположим, что зарегистрированная функция app.process_handler(event, handler_id) возвращает handler_id после обработки события.

Маршрутизация по bucket_id:

crud.storage_call(    'app.process_handler',    {event, 17},    {        bucket_id = 1205,        timeout = 0.05,    })---- returns:  - 17...

Маршрутизация по первичному ключу спейса:

local result, err = crud.storage_call(    'app.process_handler',    {event, 17},    {        space_name = 'handlers',        key = {17},        timeout = 0.05,    })---- returns:  - 17...

crud.storage_call_many(calls[, opts])

Доступно с версии TDB 3.3.0 и crud 1.8.0.

Выполнить пакет вызовов хранимых функций из box.func на мастер-узлах наборов реплик. Вызовы для одного набора реплик выполняются последовательно, а для разных наборов реплик — параллельно. Вызовы для одного сегмента сохраняют исходный порядок, а относительный порядок выполнения между разными сегментами не гарантируется. Результат возвращается в порядке исходного массива calls.

Каждая хранимая функция в вызове должна соответствовать требованиям ниже:

  • функция персистентна: функция должна быть создана в box.func с сохранённым телом (body). Lua-код функции хранится в поле body системного спейса _func и восстанавливается после перезапуска Tarantool;

  • функция должна быть задана миграцией на всех хранилищах, где может находиться сегмент. Вызов не будет выполнен, если после переноса сегмента функции не будет на нужном хранилище;

  • опция setuid задана со значением setuid = false;

  • функция должна завершать собственную локальную транзакцию. Если она оставит транзакцию открытой, модуль CRUD откатит её и вернёт ошибку этого элемента. Следующий элемент не унаследует открытую транзакцию. Пакет не является распределённой транзакцией: уже зафиксированные изменения не откатываются при ошибке другого элемента;

  • хранимая функция выполняется с правами пользователя, который вызвал метод crud.storage_call_many(). Это означает, что этот пользователь должен иметь права на вызов этой функции (execute). На роутере требуется выдать права на вызов crud.storage_call_many():

    box.schema.user.grant(    'application_user',    'execute',    'lua_call',    'crud.storage_call_many',    {if_not_exists = true})

    На хранилище требуется выдать права на выполнение нужной хранимой функции (execute), в примере это функция app.process_handler:

    box.schema.user.grant(    'application_user',    'execute',    'function',    'app.process_handler',    {if_not_exists = true})

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

Параметры:

  • calls — упорядоченный массив описаний вызовов без пропусков. Тип: table. Каждый элемент массива включает:

    • func_name — имя хранимой функции в box.func. Тип: string;
    • args — массив аргументов функции без пропусков. Тип: table. Значение по умолчанию: {};
    • bucket_id — идентификатор сегмента. Тип: number или cdata, приводимое к целому Lua-числу от 1 до количества сегментов в выбранном vshard-роутере;
    • space_name — название спейса, по первичному ключу которого вычисляется сегмент. Тип: string. Указывается вместе с параметром key, если пропущен параметр bucket_id;
    • key — значение первичного ключа спейса space_name. Тип: any — скаляр, массив частей ключа или кортеж. Указывается вместе с параметром space_name, если пропущен параметр bucket_id;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:

    • timeout — общее время ожидания выполнения всего пакета в секундах. Тип: number. Значение по умолчанию: 2. Истечение времени ожидания в timeout не отменяет уже запущенную функцию: она может завершиться и зафиксировать изменения после того, как клиент получил ошибку. На время выполнения части пакета vshard защищает затронутое хранилище от переноса сегментов;
    • vshard_router — экземпляр vshard-роутера. Тип: table.

Возвращает:

  • result — при полном или частичном успехе таблицу с массивом results, иначе nil. Порядок элементов в массиве results соответствует порядку функций в calls. Пустой массив calls возвращает {results = {}}. Каждый элемент массива results содержит одно из полей ниже:

    • returns — массив значений, возвращённых хранимой функцией. Формат значений — тот же, что и в crud.storage_call(): позиции nil заменяются на box.NULL, значение false сохраняется как есть;

    • error — описание ошибки для этого элемента. Индекс ошибки определяется по позиции result.results[i]. Поле operation_data содержит исходное описание элемента массива calls.

      Кроме того, ошибка может содержать те же поля, что и поле err в методе crud.storage_call():

      • err — описание причины;

      • func_name — имя хранимой функции;

      • bucket_id — сегмент, на который маршрутизировался вызов;

      • replicaset_id — набор реплик, на котором выполнялся вызов;

      • may_have_side_effects — могла ли функция уже изменить данные. Значение false возвращается только тогда, когда модуль CRUD точно знает, что целевая функция не запускалась (например, после проверки аргументов, при отсутствии функции или её неперсистентной регистрации, либо при отклонённых метаданных маршрутизации). Исключения при вызове целевой функции, включая ошибки доступа, помечаются значением true, поскольку ошибка могла возникнуть во вложенном вызове уже после фиксации изменений.

        Модуль crud не повторяет автоматически попытку выполнения хранимой функции, повтор вызова с may_have_side_effects = true безопасен только для идемпотентной функции.

  • err — общую ошибку всего пакета или nil. При инфраструктурной ошибке содержит поле may_have_side_effects со значением true.

Некорректный элемент calls получает собственную ошибку с may_have_side_effects = false и не мешает выполнению остальных элементов.

Пример:

Предположим, что зарегистрированная функция app.process_handler(event, handler_id) возвращает handler_id после обработки события.

crud.storage_call_many({    {        func_name = 'app.process_handler',        args = {event, 17},        bucket_id = 1205,    },    {        func_name = 'app.process_handler',        args = {event, 18},        space_name = 'handlers',        key = {18},    },}, {    timeout = 0.05,})---- results:  - returns:    - 17  - returns:    - 18...

crud.count(space_name[, conditions, opts])

Вычислить количество кортежей, удовлетворяющих условиям, по всему кластеру (распределенный count()).

Отличие от len():

  • len() — сколько всего кортежей (и для vinyl может быть приблизительно);
  • count() — считает по условиям, фактически сканируя данные (может быть затратным).

Особенности выполнения:

  • метод count() сканирует данные и делает уступку управления (yield) на экземпляры хранилища, поэтому результат может быть приблизительным в зависимости от нагрузки или изменений данных во время выполнения;
  • частота уступок управления управляется opts.yield_every.

Параметры:

  • space_name — название спейса. Тип: string;
  • conditions — массив условий для выборки. Тип: table|nil;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем;
    • yield_every — количество кортежей, обрабатываемых в хранилище для выполнения yield после завершения обработки. Тип: number. Значение опции должно быть больше 0. Значение по умолчанию: 1000;
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • force_map_call — если задано значение true, вызов map выполняется без оптимизаций, даже если указано полное условие равенства первичного ключа. Тип: boolean;
    • fullscan — если задано значение true, критическая запись в журнале будет пропущена при потенциально длительном count. Тип: boolean;
    • mode — режим доступа. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: read;
    • prefer_replica — если задано значение true, предпочитаемой целью для выполнения запроса на выборку будет один из экземпляров реплики. Тип: boolean;
    • balance — если задано значение true, включена балансировка нагрузки. Тип: boolean.

Возвращает:

  • count — количество или nil при ошибке;
  • err — ошибку или nil.

Пример:

local n, err = crud.count('customers', {{'==', 'age', 35}})

crud.locate(space_name, key[, opts])

Доступно с версий TDB 3.2.0 и CRUD 1.7.5.

Определить, на каком движке хранения (memtx или vinyl) в данный момент находится кортеж. Метод работает только для спейсов, участвующих в архивации с использованием модуля cooler.

Параметры:

  • space_name — название спейса. Тип: string;
  • key — значение первичного ключа. Тип: any;
  • opts — дополнительные параметры (опциональны). Тип: table. Поддерживаемые параметры:
    • bucket_id — идентификатор сегмента. Тип: number или cdata;
    • timeout — время, в течение которого роутер ожидает ответ от узла хранилища (в секундах). Тип: number. Если роутер не может определить шард с указанным bucket_id, то CRUD возвращает ошибку маршрутизации. По умолчанию: 2;
    • request_timeout — время ожидания в секундах, служит защитой от зависания реплик. Тип: number. Передавать параметры request_timeout и timeout нужно вместе с учетом следующего условия: timeout > request_timeout. Параметр request_timeout определяет, сколько времени может занять одна попытка запроса. По истечении этого времени (когда возникает ошибка TimedOut) роутер повторяет запрос на следующей реплике, если значение опции timeout еще не истекло; Может быть задан только при mode = read. Значение по умолчанию совпадает со значением опции timeout, передаваемой пользователем;
    • mode — режим доступа. Тип: string. Поддерживаемые значения: read, write. Если задано значение write, запрос на выборку выполняется на мастер-узле. Значение по умолчанию: read;
    • prefer_replica — если задано значение true, предпочитаемой целью для выполнения запроса на выборку будет один из экземпляров реплики. Тип: boolean;
    • balance — если задано значение true, включена балансировка нагрузки. Тип: boolean.

Возвращает:

  • result — 'memtx' или 'vinyl', если кортеж найден;
  • nil — если кортеж отсутствует на целевом узле хранилища;
  • nil, err — если произошла ошибка.

Пример:

crud.locate('customers', 100)-- - memtx-- - nullcrud.locate('customers', 200)-- - vinyl-- - nullcrud.locate('customers', 999) -- кортеж не существует-- - null-- - null
Была ли статья полезна?