Миграции | Tarantool
Документация на русском языке
поддерживается сообществом

Миграции

Миграцией называется любое изменение схемы данных: добавление/удаление поля, добавление/удаление индекса, изменение формата поля и т. д.

В Tarantool есть только два вида миграции схемы, при которых не нужно мигрировать данные:

  • добавление поля в конец спейса
  • добавление индекса

Примечание

Check the Upgrading space schema section in the Enterprise version. With the help of space:upgrade() feature, you can enable compression and migrate, including already created tuples.

Добавление поля происходит следующим образом:

local users = box.space.users
local fmt = users:format()

table.insert(fmt, { name = 'age', type = 'number', is_nullable = true })
users:format(fmt)

Обратите внимание: поле обязательно должно иметь параметр is_nullable. Иначе произойдет ошибка.

После создания нового поля, вы, вероятно, захотите заполнить его данными. Для этой задачи удобно использовать модуль tarantool/moonwalker. В README есть описание того, как начать его использовать.

Про добавление индекса рассказывается в описании метода space_object:create_index().

Остальные виды миграций также возможны, однако поддерживать консистентность данных при этом сложнее.

Миграции можно выполнять в двух случаях:

  • при старте Tarantool, пока ни один клиент еще не использует БД
  • в процессе обработки запросов, когда у БД уже есть активные клиенты

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

Мы выделяем следующие проблемы при наличии активных клиентов:

  • Связанные данные могут атомарно изменяться.
  • Нужно уметь отдавать данные как по новой схеме, так и по старой.
  • Когда данные перемещают в новый спейс, доступ к данным должен учитывать, что данные могут быть как в одном спейсе, так и в другом.
  • Запросы на запись не должны мешать корректной миграции. Типичный подход: всегда писать по новой схеме.

Эти проблемы могут быть или не быть релевантными в зависимости от вашего приложения и требований к его доступности.

В Tarantool есть механизм транзакций. Он полезен при написании миграции, так как позволяет атомарно работать с данными. Но перед использованием механизма транзакций нужно знать об ограничениях.

Подробнее о них описано в разделе про транзакции.

Код миграций исполняется на запущенном инстансе Tarantool. Важно: ни один способ не гарантирует вам транзакционное применение миграций на всем кластере.

Способ 1: написать миграции в коде основного приложения

Это довольно просто: когда вы перезагружаете код, в нужный момент происходит миграция данных и схема базы данных обновляется. Однако такой способ может подойти не всем. У вас может не быть возможности перезапустить Tarantool или обновить код через механизм горячей перезагрузки (hot reload).

Способ 2: tarantool/migrations (только для кластера на Tarantool Cartridge)

Про этот способ подробнее написано в README самого модуля tarantool/migrations.

Примечание

Есть также два способа, которые мы не рекомендуем использовать, но вы можете найти их полезными по тем или иным причинам.

Cпособ 3: утилита tarantoolctl

Утилита tarantoolctl поставляется вместе с Tarantool. Подключитесь к нужному инстансу через команду tarantoolctl connect.

$ tarantoolctl connect admin:password@localhost:3301
  • Если ваша миграция написана в Lua файле, вы можете исполнить его с помощью функции dofile(). Вызовите ее и первым аргументом укажите путь до файла с миграцией. Выглядит это вот так:

    tarantool> dofile('0001-delete-space.lua')
    ---
    ...
    
  • (или) можно скопировать код скрипта миграции, вставить его в консоль и применить.

Способ 4: применение миграции с помощью Ansible

Если вы используете Ansible-роль для развёртывания кластера Tarantool, то вы можете применить eval. Прочитать подробнее про eval можно в документации по Ansible-роли.

Нашли ответ на свой вопрос?
Обратная связь