Рейтинг@Mail.ru

Администрирование серверной части

Замечание

Документация находится в процессе перевода и может отставать от английской версии.

Администрирование серверной части

Typical server administration tasks include starting and stopping instances of the server, reloading configuration, taking snapshots, log rotation.

Using Tarantool as a client

Если tarantool запущен без файла инициализации, или же в файле инициализации указана функция console.start(), то tarantool стартует в интерактивном режиме: он выводит приглашение командной строки (“tarantool>”), и запросы можно вводить прямо в консоли. В таком режиме tarantool можно использовать в качестве клиента для удаленного сервера.

В этом разделе описаны синтаксические правила для ввода запросов в консоли Tarantool’а, с примечаниями и примерами. Другие клиентские программы могут иметь схожие параметры и синтаксис запросов. Некоторые сведения из этого раздела дублируются в главе Справочник по конфигурированию.

Условные обозначения, используемые в этом разделе

Токены — это последовательности символов, которые рассматриваются как синтаксические единицы в рамках запроса. Квадратные скобки [ и ] используются для обозначения необязательных токенов. Три точки в строке ... означают, что предыдущие токены могут повторяться. Вертикальная черта | означает, что предыдущие и последующие токены являются взаимоисключающими альтернативами.

Параметры запуска клиента из командной строки

Общий вид:

$ tarantool
ИЛИ
$ tarantool опции
ИЛИ
$ tarantool файл-инициализации-на-lua [ аргументы ]

файл-инициализации-на-lua — это любой скрипт, содержащий логику инициализации. Код из этого файла выполняется при запуске Tarantool’а. Например: init.lua.
Примечания: При использовании скрипта, Tarantool не выводит приглашение командной строки. Скрипт должен содержать конфигурационные настройки, в т.ч. box.cfg...listen=... или box.listen(...), чтобы внешние программы могли установить соединение с Tarantool-сервером на одном из указанных портов.

Опция — это одно из следующих значений (указаны в алфавитном порядке, по полному имени опции):

-?, -h, --help

Tarantool-клиент выводит краткую справку, включая список всех параметров. Например: tarantool --help. Вывод останавливается после показа справки.

-V, --version

Tarantool-клиент выводит свой номер версии. Например: tarantool --version. Вывод останавливается после показа номера версии.

Токены, запросы и специальные комбинации клавиш

Идентификатором процедуры может быть любая последовательность букв, цифр и/или подчеркиваний, которая отвечает правилам именования идентификаторов в Lua. Термин “идентификаторы процедур” также применяют к именам функций.
Примечание: в случае с именами функций регистр имеет значение, поэтому insert и Insert — это не одно и то же.

Строковым литералом может быть любая последовательность из нуля и более символов, которая заключена в одинарные кавычки. Двойные кавычки также допустимы, но предпочтительным вариантом являются одинарные кавычки. А двойные квадратные скобки нужны для многострочных литералов (см. документацию по языку Lua).
Например: ‘Hello, world’, ‘A’, [[A\B!]].

Числовым литералом может быть любая последовательность символов, состоящая из одной и более цифр с необязательным знаком + или - в начале. В состав больших числовых литералов, а также числовых литералов с плавающей точкой может входить десятичный разделитель (запятая или точка), символы для экспоненциального представления и суффиксы.
Например: 500, -500, 5e2, 500.1, 5LL, 5ULL.

Однобайтовым символом может быть запятая, открывающая или закрывающая круглая скобка, а также арифметический оператор.
Например: * , ( ).

Токены должны разделяться одним или бОльшим количеством пробелов. Исключением являются однобайтовые токены и строковые литералы — вокруг них пробелы не нужны.

Запросы

Запросы вводятся после приглашения командной строки, когда Tarantool работает в интерактивном режиме. (Приглашение — это слово tarantool и знак “больше”, вот так: tarantool>). Маркером конца запроса по умолчанию является перевод строки.

Для ввода многострочных запросов можно задать другой маркер конца запроса. Для этого введите команду следующего вида: console = require('console'); console.delimiter(новый-маркер). В качестве нового маркера укажите строковый литерал в одинарных кавычках. После этого вам нужно будет вводить указанный маркер в конце каждого запроса, потому что Tarantool перестанет интерпретировать перевод строки как конец запроса. Чтобы вернуться к обычному режиму, введите: console.delimiter('')string-literal. Как правило, задавать свой маркер нет необходимости, поскольку Tarantool сам распознает, что запрос введен не полностью (скажем, когда Tarantool не встречает слова end в объявлении функции). Например:

console = require('console'); console.delimiter('!')
function f ()
  statement_1 = 'a'
  statement_2 = 'b'
end!
console.delimiter('')!

См. также описание формата клиентских запросов в виде аннотированных BNF-диаграмм (Backus-Naur Form).

Работая в интерактивном режиме, Tarantool-сервер принимает введенные запросы и выводит результаты. Запросы, как правило, вводит пользователь. Вот пример интерактивной пользовательской сессии:

$ tarantool
[ здесь tarantool выводит приветствие и номер версии ]
tarantool> box.cfg{listen = 3301}
[ здесь tarantool выводит свои текущие настройки ]
tarantool> s = box.schema.space.create('tester')
[ здесь tarantool может вывести сообщение о том,
  что идет обработка запроса ]
---
...
tarantool> s:create_index('primary', {type = 'hash', parts = {1, 'unsigned'}})
---
...
tarantool> box.space.tester:insert{1,'My first tuple'}
---
- [1, 'My first tuple']
...
tarantool> box.space.tester:select(1)
---
- - [1, 'My first tuple']
...
tarantool> box.space.tester:drop()
---
...
tarantool> os.exit()
2014-04-30 10:28:00.886 [20436] main/101/spawner I> Exiting: master shutdown
$

Пояснения к приведенному выше примеру:

  • На многие запросы Tarantool возвращает типизированные объекты. В ответ на запрос box.cfglisten=3301 Tarantool выведет результат на экран. Если в запросе задано, что его результат должен быть записан в некоторую переменную, например c = box.cfglisten=3301, то в таком случае вывода результата на экран не происходит.

  • Вывод объекта в Tarantool’е всегда начинается со строки “---” и заканчивается строкой “...”.

  • По запросу на вставку данных возвращается объект типа кортеж (tuple), и в этом случае перед выводом будет стоять одиночное тире (‘-‘). А по запросу на выборку данных возвращается объект типа таблица кортежей (table of tuples), и в этом случае перед выводом будут стоять два тире (‘- -‘).

Утилита tarantoolctl

With tarantoolctl, you can say: “start an instance of the Tarantool server which runs a single user-written Lua program, allocating disk resources specifically for that program, via a standardized deployment method.”

If Tarantool was installed with Debian or Red Hat installation packages, the script is in /usr/bin/tarantoolctl or /usr/local/bin/tarantoolctl. The script handles such things as: starting, stopping, rotating logs, logging in to the application’s console, and checking status.

Also, you can use tarantoolctl as a client to connect to another instance of Tarantool server and pass requests.

Конфигурирование tarantoolctl

Скрипт tarantoolctl сначала проверяет наличие файла конфигурации в текущей директории ($PWD/.tarantoolctl). Если не находит, то проверяет домашнюю директорию текущего пользователя ($HOME/.config/tarantool/tarantool). Если опять не находит, то проверяет директорию, указанную в переменной SYSCONFDIR (обычно это /etc/sysconfig/tarantool, но на разных платформах этот путь может различаться). Большинство параметров tarantoolctl аналогичны тем, что задаются в запросе box.cfg...; однако tarantoolctl меняет значение некоторых параметров, дописывая к ним имя приложения. Далее приводится копия файла usr/local/etc/default/tarantool, где для всех параметров указаны их значения по умолчанию:

default_cfg = {
    pid_file   = "/var/run/tarantool",
    wal_dir    = "/var/lib/tarantool",
    memtx_dir  = "/var/lib/tarantool",
    vinyl_dir  = "/var/lib/tarantool",
    log     = "/var/log/tarantool",
    username   = "tarantool",
}
instance_dir = "/etc/tarantool/instances.enabled"

Комментарии к параметрам в приведенном выше скрипте:

pid_file

Директория, где хранятся pid-файл и socket-файл. Скрипт tarantoolctl добавляет “/instance-name” к имени директории.

wal_dir

Директория, где хранятся *.xlog-файлы. Скрипт tarantoolctl добавляет “/instance-name” к имени директории.

memtx_dir

Директория, где хранятся *.snap-файлы. Скрипт tarantoolctl добавляет “/instance-name” к имени директории.

vinyl_dir

Директория, где хранятся файлы движка vinyl. Скрипт tarantoolctl добавляет “/instance-name” к имени директории.

log

Директория, где хранятся файлы журнала с сообщениями от Tarantool-приложений. Скрипт tarantoolctl добавляет “/instance-name” к имени директории.

username
The user that runs the Tarantool instance. This is the operating-system user name rather than the Tarantool-client user name.
instance_dir

Имя директории, где хранятся исходные файлы всех Tarantool-приложений для данного хоста. Пользователю, который пишет приложение для tarantoolctl, нужно положить исходный код своего приложения в эту директорию или настроить симлинк. Далее для примеров в этом разделе мы используем Tarantool-приложение с именем my_app, и его исходный код должен лежать в файле instance_dir/my_app.lua.

Команды для tarantoolctl

Команды для tarantoolctl имеют вид tarantoolctl операция имя_приложения. В качестве операции можно указать одно из следующих значений: start, stop, enter, logrotate, status, eval.

start <application>

Запустить приложение с именем <application>

stop <application>

Остановить приложение

enter <application>

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

logrotate <application>

Произвести ротацию журналов указанного приложения (создать новые, удалить старые)

status <application>

Проверить статус приложения

eval <application> <scriptname>

Выполнить код из файла <scriptname> от имени запущенного экземпляра приложения <application>

connect <URI>

Connect to a Tarantool instance running at the specified URI

Примеры кода для tarantoolctl

Проверить, запущено ли приложение my_app:

if tarantoolctl status my_app; then
...
fi

Выполнить инструкции из файла init.d во время запуска приложения:

for (каждый файл в директории instance_dir):
    tarantoolctl start `basename $ file .lua`

Указать файл конфигурации для ротации журнала, например:

/path/to/tarantool/*.log {
    daily
    size 512k
    missingok
    rotate 10
    compress
    delaycompress
    create 0640 tarantool adm
    postrotate
        /path/to/tarantoolctl logrotate basename $ 1 .log
    endscript
}

Подробный пример для tarantoolctl

The example’s objective is to make a temporary directory where tarantoolctl can start a long-running application and monitor it.

Итак, наши исходные условия: нам известен пароль root-пользователя; компьютер используется только для тестирования; Tarantool-сервер настроен и готов к запуску, но пока еще не запущен ;программа tarantoolctl установлена в пользовательском окружении; пока не существует директории с именем tarantool_test.

Создадим директорию с именем /tarantool_test:

$ sudo mkdir /tarantool_test

Отредактируем файл /usr/local/etc/default/tarantool. Для этого нам сначала может понадобиться выполнить команду sudo mkdir /usr/local/etc/default. Указанный файл будет содержать следующие настройки:

default_cfg = {
    pid_file  = "/tarantool_test/my_app.pid",
    wal_dir   = "/tarantool_test",
    memtx_dir = "/tarantool_test",
    vinyl_dir = "/tarantool_test",
    log       = "/tarantool_test/log",
    username  = "tarantool",
}
instance_dir = "/tarantool_test"

Создадим файл /tarantool_test/my_app.lua для приложения my_app:

box.cfg{listen = 3301}
box.schema.user.passwd('Gx5!')
box.schema.user.grant('guest','read,write,execute','universe')
fiber = require('fiber')
box.schema.space.create('tester')
box.space.tester:create_index('primary',{})
i = 0
while 0 == 0 do
    fiber.sleep(5)
    i = i + 1
    print('insert ' .. i)
    box.space.tester:insert{i, 'my_app tuple'}
end

С помощью tarantoolctl запустим наше приложение...

$ cd /tarantool_test
$ sudo tarantoolctl start my_app

... и получим сообщения о том, что экземпляр нашего приложения запущен. Затем скажем:

$ ls -l /tarantool_test/my_app

... и увидим .snap-файл и .xlog-файл. Затем скажем:

$ sudo less /tarantool_test/log/my_app.log

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

$ cd /tarantool_test
$ # assume that 'tarantool' invokes a Tarantool instance
$ sudo tarantool
tarantool> box.cfg{}
tarantool> console = require('console')
tarantool> console.connect('localhost:3301')
tarantool> box.space.tester:select({0}, {iterator = 'GE'})

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

Всё. Теперь остановим приложение my_app. Единственный корректный способ — это использовать tarantoolctl:

$ sudo tarantoolctl stop my_app

Почистим систему после тестирования. Приведем содержимое файла /usr/local/etc/default/tarantool к исходному виду и удалим нашу тестовую директорию:

$ cd /
$ sudo rm -R tarantool_test

An example for tarantoolctl connect

$ tarantoolctl connect username:password@127.0.0.1:3306

Примечание

There are alternatives to tarantoolctl connect – you can use the console module or the net.box module from a Tarantool server. Also, you can write your client programs with any of the Connectors. However, most of the examples in this manual illustrate usage with either tarantoolctl connect or with using the Tarantool server as a client.

Служебные порты

Термины “порт для администрирования”, “консоль для администрирования”, “текстовый протокол” относятся к установке соединения с помощью console.listen(...) для ввода запросов от администраторов.

Термины “бинарный порт”, “бинарный протокол”, “первичный порт” относятся к другому виду соединения — тому, что устанавливается с помощью параметра box.cfg{listen=...} и предназначено для ввода запросов от любых пользователей.

Ordinary connections to the Tarantool instance should go via a binary port. But admin ports are useful for special cases involving security.

При установке соединение через порт для администрирования:

  • Пароль не требуется

  • Пользователь автоматически получает привилегии администратора.

Поэтому порты для администрирования следует настраивать очень осторожно. Если это TCP-порт, то он должен быть открыть только для определенного IP-адреса. В идеале мы рекомендуем вовсе не использовать TCP-порты. Вместо них лучше настроить доменный Unix-сокет, который требует настройки прав доступа к серверной машине. Тогда типичная настройка порта для администрирования будет выглядеть следующим образом:

console.listen('/var/lib/tarantool/socket_name.sock')

а типичный URI для соединения будет таким:

admin:any_string@/var/lib/tarantool/socket_name.sock

Это в том случае, если у сервера (listener’а) есть привилегии на запись в файл /var/lib/tarantool, а на стороне клиента (connector’а) есть привилегии на чтение из того же файла. Аналогично можно установить соединение и задать настройки с помощью tarantoolctl.

Если не задан пароль администратора, который можно сообщить пользователям, а порты для администрирования настроены с ограничением доступа по IP либо через сокеты, то запросы, требующие привилегий администратора, можно делать только локально, где вопросы безопасности и мониторинга регулируются с помощью средств Unix-системы.

В целях дополнительной безопасности некоторые запросы на портах для администрирования запрещены. Например, conn:eval вернет сообщение об ошибке - error: console does not support this request type, поскольку запрос conn:eval должен осуществляться в рамках бинарного протокола.

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

Выяснить, является ли некий TCP-порт портом для администрирования, можно с помощью telnet. Например:

$ telnet 0 3303
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
Tarantool 1.7.2-70-gbc479ad (Lua console)
type 'help' for interactive help

В этом примере в ответе от сервера нет слова “binary” и есть слова “Lua console”. Это значит, что мы установили соединение на порту для администрирования и можем вводить администраторские запросы на этом терминале.

Служебные запросы

To learn which functions are considered to be administrative, type help(). A reference description also follows below:

box.snapshot()

Take a snapshot of all data and store it in memtx_dir/<latest-lsn>.snap. To take a snapshot, Tarantool first enters the delayed garbage collection mode for all data. In this mode, tuples which were allocated before the snapshot has started are not freed until the snapshot has finished. To preserve consistency of the primary key, used to iterate over tuples, a copy-on-write technique is employed. If the master process changes part of a primary key, the corresponding process page is split, and the snapshot process obtains an old copy of the page. In effect, the snapshot process uses multi-version concurrency control in order to avoid copying changes which are superseded while it is running.

Since a snapshot is written sequentially, one can expect a very high write performance (averaging to 80MB/second on modern disks), which means an average database instance gets saved in a matter of minutes.

Примечание

As long as there are any changes to the parent index memory through concurrent updates, there are going to be page splits, and therefore you need to have some extra free memory to run this command. 10% of memtx_memory is, on average, sufficient. This statement waits until a snapshot is taken and returns operation result.

Примечание

Change notice: Prior to Tarantool version 1.6.6, the snapshot process caused a fork, which could cause occasional latency spikes. Starting with Tarantool version 1.6.6, the snapshot process creates a consistent read view and writes this view to the snapshot file from a separate thread.

Although box.snapshot() does not cause a fork, there is a separate fiber which may produce snapshots at regular intervals – see the discussion of the snapshot daemon.

Example:

tarantool> box.info.version
---
- 1.7.0-1216-g73f7154
...
tarantool> box.snapshot()
---
- ok
...
tarantool> box.snapshot()
---
- error: can't save snapshot, errno 17 (File exists)
...

Taking a snapshot does not cause the server to start a new write-ahead log. Once a snapshot is taken, old WALs can be deleted as long as all replicated data is up to date. But the WAL which was current at the time box.snapshot() started must be kept for recovery, since it still contains log records written after the start of box.snapshot().

An alternative way to save a snapshot is to send a SIGUSR1 signal to the instance. While this approach could be handy, it is not recommended for use in automation: a signal provides no way to find out whether the snapshot was taken successfully or not.

Просмотр состояния сервера

For server instance introspection, use the reports provided by functions in the following submodules:

  • box.cfg submodule (check and specify all configuration parameters for the Tarantool instance)
  • box.slab submodule (monitor the total use and fragmentation of memory allocated for storing data in Tarantool)
  • box.info submodule (introspect Tarantool’s server variables)
  • box.stat submodule (introspect Tarantool’s request and network statistics)

Резервное копирование

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

Cold backup

Суть процедуры: последний созданный Tarantool’ом файл-снимок является резервной копией всей базы; а WAL-файлы, созданные следом, являются инкрементными копиями. Поэтому вся процедура резервирования сводится к копированию последнего файла-снимка и последующих WAL-файлов.

  1. Prevent all users from writing to the database. This can be done by shutting down the instance, or by saying box.cfg{read_only=true} and then ensuring that all earlier writes are complete (fsync can be used for this purpose).
  2. Если вы хотите создать резеврную копию для всей базы целиком, введите запрос box.snapshot().

  3. Use tar to make a (possibly compressed) copy of the latest .snap and .xlog files on the memtx_dir and wal_dir directories.
  4. Если того требуют правила безопасности, зашифруйте получившийся tar-файл.

  5. Скопируйте tar-файл в надежное место.

... Later, restoring the database is a matter of taking the tar file and putting its contents back in the memtx_dir and wal_dir directories.

Continuous remote backup

In essence: replication is useful for backup as well as for load balancing. Therefore taking a backup is a matter of ensuring that any given replica has an up-to-date copy of the data, and doing a cold backup on that. Since all the other replicas continue to operate, this is not a cold backup from the end user’s point of view. This could be done on a regular basis, with a cron job or with a Tarantool fiber.

Hot backup

Суть процедуры: по ходу работы системы нужно сохранять записи об изменениях, сделанных со времени последнего “холодного” резервирования.

Для этого вам понадобится специальная утилита для копирования частей файлов (например, rsync), которая позволит удаленно и на постоянной основе копировать только изменившиеся части файлов-снимков и WAL-файлов, а не все эти файлы целиком.

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

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

Обновление сервера и базы данных

Обновление Tarantool’а в условиях эксплуатации

Во-первых, вынесите всю бизнес-логику своего приложения в отдельный Tarantool-модуль на языке Lua так, чтобы все нужные функции были доступны для вызова извне (CALL).

Вот пример такого модуля, файл /usr/share/tarantool/myapp.lua:

local function start()
  -- Initial version
  box.once("myapp:.1.0", function()
  box.schema.space.create("somedata")
  box.space.somedata:create_index("primary")
  ...

  -- migration code from 1.0 to 1.1
  box.once("myapp:.v1.1", function()
  box.space.somedata.index.primary:alter(...)
  ...

  -- migration code from 1.1 to 1.2
  box.once("myapp:.v1.2", function()
  box.space.somedata.space:alter(...)
  box.space.somedata:insert(...)
  ...
end

-- start some background fibers if you need

local function stop()
  -- stop all background fibers and cleanup resources
end

local function api_for_call(xxx)
  -- do some business
end

return {
  start = start;
  stop = stop;
  api_for_call = api_for_call;
}

Поддержка этого файла лежит на стороне разработчиков приложения. А команда разработки Tarantool’а со своей стороны предлагает шаблоны, для того чтобы вы могли создать у себя deb/rpm-сборку, а также утилиты для быстрого создания сборок под разные платформы. Если понадобится, вы можете разбить приложения на отдельные файлы и/или модули.

Во вторых, положите скрипт инициализации в директорию /etc/tarantool/instances.available.

Вот пример такого скрипта, файл /etc/tarantool/instances.available/myappcfg.lua:

#!/usr/bin/env tarantool

box.cfg {
  listen = 3301;
}

if myapp ~= nil then
  -- hot code reload using tarantoolctl or dofile()

  -- unload old application
  myapp.stop()
  -- clear cache for loaded modules and dependencies
  package.loaded['myapp'] = nil
  package.loaded['somedep'] = nil; -- dependency of 'myapp'
end

-- load a new version of app and all dependencies
myapp = require('myapp').start({some app options controlled by sysadmins})

Более детальный пример (со всеми настройками) содержится в файле example.lua, который входит в состав дистрибутива Tarantool’а.

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

Теперь обновите файл с вашим приложением в директории /usr/share/tarantool. Замените старую версию файла (например, /usr/share/tarantool/myapp.lua) и вручную загрузите скрипт инициализации myappcfg.lua с помощью утилиты tarantoolctl:

$ tarantoolctl eval /etc/tarantool/instance.enabled/myappcfg.lua

После этого вам нужно вручную очистить кеш модулей package.loaded.

Чтобы создать deb/rpm-сборку, вы можете добавить инструкцию tarantoolctl eval прямо в спецификацию Tarantool’а в файле RPM.spec и в директории /debian.

В итоге клиенты делают вызов (CALL) функции myapp.api_for_call и других функций из API.

Если вы используете tarantool-http, то запускать бинарный протокол не нужно.

Upgrading a Tarantool database

Эта информация полезна в том случае, если у вас есть база данных, работающая на какой-либо старой версии Tarantool’а, а теперь вы установили Tarantool новой версии. В этом случае выполните запрос box.schema.upgrade().

Например, вот что происходит, если выполнить запрос box.schema.upgrade() для базы, созданной в начале 2015 года (для примера показана лишь малая часть выводимых сообщений):

tarantool> box.schema.upgrade()
alter index primary on _space set options to {"unique":true}, parts to [[0,"unsigned"]]
alter space _schema set options to {}
create view _vindex...
grant read access to 'public' role for _vindex view
set schema version to 1.7.0
---
...

Обработка сигналов от сервера

Во время основного цикла Tarantool-сервер обрабатывает следующие сигналы:

SIGHUP

может привести к ротации лога, см. пример в разделе “Запись в журнал”.

SIGUSR1

может привести к сохранению снимка, см. описание функции box.snapshot.

SIGTERM

может привести к корректному завершению работы (с предварительным сохранением всех данных).

SIGINT

(или “прерывание с клавиатуры”) может привести к корректному завершению работы (с предварительным сохранением всех данных).

SIGKILL

приводит к аварийному завершению работы (с возможной потерей данных).

Other signals will result in behavior defined by the operating system. Signals other than SIGKILL may be ignored, especially if the instance is executing a long-running procedure which prevents return to the main thread event loop.

Generating a core file

On rare occasions it may be necessary to generate a core file from the server. For example, the Tarantool developers may request one for a bug report. First make sure core dumps are enabled on the system (this may require some study of the system settings and administrative privileges).

Find out the process id of the instance. This is the value in box.info.pid. It can also be found with utilities such as ps -A | grep tarantool. We will refer to this process id as $PID.

Either run the debugger:

gdb -batch -ex "generate-core-file" -p $PID

or stop the instance with a SIGABRT signal:

kill -SIGABRT $PID

Since Tarantool stores tuples in memory, core files may be large.

Название процесса

Операционные системы Linux и FreeBSD позволяют запущенному процессу менять его название (title), в котором изначально содержится имя программы (name). Tarantool использует эту возможность, чтобы упростить работу системного администратора, например посмотреть, какие службы запущены на хосте, их статус и т.д.

A Tarantool instance’s process title has these components:

имя_программы [имя_файла_инициализации] <имя_роли> [название_процесса]

  • имя_программы — это, как правило, “tarantool”.

  • имя_файла_инициализации — это имя файла инициализации на Lua, если этот файл был указан при запуске.

  • имя_роли — это может быть один из следующих вариантов:

    • “running” (узел находится в режиме “готов к принятию запросов”),

    • “loading” (узел, который загружает данные из ранее сохраненного снимка и WAL-файла),

    • “orphan” (узел не входит в состав кластера),

    • “hot_standby”, or
    • “dumper” + process-id (идет сохранение снимка).

  • название_процесса — это необязательное название Tarantool-процесса в системе, которое берется из конфигурационного параметра custom_proc_title, если он указан.

Например:

$ ps -AF | grep tarantool
1000     17337 16716  1 91362  6916   0 11:07 pts/5    00:00:13 tarantool script.lua <running>

Заметки по администрированию для разных платформ

This section will contain information about issues or features which exist on some platforms but not others - for example, on certain versions of a particular Linux distribution.

Debian GNU/Linux and Ubuntu

Настройка конкретного экземпляра Tarantool-сервера:

$ ln -s /etc/tarantool/instances.available/*instance-name.cfg* /etc/tarantool/instances.enabled/

Запуск всех экземпляров:

$ service tarantool start

Остановка всех экземпляров:

$ service tarantool stop

Запуск/остановка конкретного экземпляра:

$ service tarantool-instance-name start/stop

Fedora, RHEL, CentOS

Известных воспроизводящихся дефектов для данных платформ нет. Если вы столкнулись с плавающим дефектом, посмотрите описания проблем на странице http://github.com/tarantool/tarantool/issues, введя в строке поиска слово “RHEL”, “CentOS”, “Fedora” или “Red Hat”.

FreeBSD

Известных воспроизводящихся дефектов для данной платформы нет. Если вы столкнулись с плавающим дефектом, посмотрите описания проблем на странице http://github.com/tarantool/tarantool/issues, введя в строке поиска слово “FreeBSD”.

Mac OS X

Известных воспроизводящихся дефектов для данных платформ нет. Если вы столкнулись с плавающим дефектом, посмотрите описания проблем на странице http://github.com/tarantool/tarantool/issues, введя в строке поиска слово “OS X”.

Заметки для пользователей systemd

Tarantool полностью поддерживает работу с systemd как со средством для управления экземплярами и контроля за фоновыми программами базы данных.

Управление экземплярами

В архитектуре Tarantool’а заложена возможность запуска сразу многих экземпляров Tarantool-сервера на одной машине. С помощью systemctl start|stop|restart|status tarantool@$MYAPP можно управлять базами данных и Lua-приложениями.

Создание экземпляров

Задайте все настройки в виде Lua-скрипта и поместите их в файл /etc/tarantool/instances.available/$MYAPP.lua:

box.cfg{listen = 3313}
require('myappcode').start()

(это пример минимально достаточной конфигурации).

Также вы можете посмотреть пример Lua-скрипт в файле example.lua, который входит в состав дистрибутива Tarantool’а и содержит значения всех опций.

Запуск экземпляров

Для запуска экземпляра ${MYAPP} выполните команду systemctl start tarantool@$MYAPP:

$ systemctl start tarantool@example
$ ps axuf|grep exampl[e]
taranto+  5350  1.3  0.3 1448872 7736 ?        Ssl  20:05   0:28 tarantool example.lua <running>

(здесь и далее мы приводим примеры консольного вывода для Fedora).

Для автоматической загрузки экземпляра ${MYAPP} во время запуска всей системы используйте команду systemctl enable tarantool@$MYAPP.

Мониторинг экземпляров

Для проверки информации об экземпляре ${MYAPP} выполните команду systemctl status tarantool@$MYAPP:

$ systemctl status tarantool@example
tarantool@example.service - Tarantool Database Server
Loaded: loaded (/etc/systemd/system/tarantool@.service; disabled; vendor preset: disabled)
Active: active (running)
Docs: man:tarantool(1)
Process: 5346 ExecStart=/usr/bin/tarantoolctl start %I (code=exited, status=0/SUCCESS)
Main PID: 5350 (tarantool)
Tasks: 11 (limit: 512)
CGroup: /system.slice/system-tarantool.slice/tarantool@example.service
+ 5350 tarantool example.lua <running>

Для проверки журнала загрузки выполните команду journalctl -u tarantool@$MYAPP:

$ journalctl -u tarantool@example -n 5
-- Logs begin at Fri 2016-01-08 12:21:53 MSK, end at Thu 2016-01-21 21:17:47 MSK. --
Jan 21 21:17:47 localhost.localdomain systemd[1]: Stopped Tarantool Database Server.
Jan 21 21:17:47 localhost.localdomain systemd[1]: Starting Tarantool Database Server...
Jan 21 21:17:47 localhost.localdomain tarantoolctl[5969]: /usr/bin/tarantoolctl: Found example.lua in /etc/tarantool/instances.available
Jan 21 21:17:47 localhost.localdomain tarantoolctl[5969]: /usr/bin/tarantoolctl: Starting instance...
Jan 21 21:17:47 localhost.localdomain systemd[1]: Started Tarantool Database Server

Подсоединение к экземплярам

Вы можете подсоединиться к запущенному экземпляру Tarantool-сервера и выполнить некий Lua-скрипт с помощью утилиты tarantoolctl:

$ tarantoolctl enter example
/bin/tarantoolctl: Found example.lua in /etc/tarantool/instances.available
/bin/tarantoolctl: Connecting to /var/run/tarantool/example.control
/bin/tarantoolctl: connected to unix/:/var/run/tarantool/example.control
unix/:/var/run/tarantool/example.control> 1 + 1
---
- 2
...
unix/:/var/run/tarantool/example.control>

Проверка журнала

Tarantool ведет записи о важных событиях в файле /var/log/tarantool/$MYAPP.log.

Давайте запишем что-нибудь в файл журнала:

$ tarantoolctl enter example
/bin/tarantoolctl: Found example.lua in /etc/tarantool/instances.available
/bin/tarantoolctl: Connecting to /var/run/tarantool/example.control
/bin/tarantoolctl: connected to unix/:/var/run/tarantool/example.control
unix/:/var/run/tarantool/example.control> require('log').info("Hello for README.systemd readers")
---
...

Затем проверим содержимое журнала:

$ tail /var/log/tarantool/example.log
2016-01-21 21:09:45.982 [5914] iproto I> binary: started
2016-01-21 21:09:45.982 [5914] iproto I> binary: bound to 0.0.0.0:3301
2016-01-21 21:09:45.983 [5914] main/101/tarantoolctl I> ready to accept requests
2016-01-21 21:09:45.983 [5914] main/101/example I> Run console at /var/run/tarantool/example.control
2016-01-21 21:09:45.984 [5914] main/101/example I> tcp_server: remove dead UNIX socket: /var/run/tarantool/example.control
2016-01-21 21:09:45.984 [5914] main/104/console/unix/:/var/run/tarant I> started
2016-01-21 21:09:45.985 [5914] main C> entering the event loop
2016-01-21 21:14:43.320 [5914] main/105/console/unix/: I> client unix/: connected
2016-01-21 21:15:07.115 [5914] main/105/console/unix/: I> Hello for README.systemd readers
2016-01-21 21:15:09.250 [5914] main/105/console/unix/: I> client unix/: disconnected

Для ротации журнала нужно установить программу logrotate. Настройки для ротации можно задать в файле /etc/logrotate.d/tarantool.

Остановка экземпляров

Для просмотра информации о запущенном экземпляре ${MYAPP} выполните команду systemctl stop tarantool@$MYAPP.

$ systemctl stop tarantool@example

Контроль за фоновыми программами

Если какой-либо экземпляр Tarantool-сервера выходит из строя, systemd автоматически перезапускает его.

Давайте попробуем вывести из строя один экземпляр:

$ systemctl status tarantool@example|grep PID
Main PID: 5885 (tarantool)
$ tarantoolctl enter example
/bin/tarantoolctl: Found example.lua in /etc/tarantool/instances.available
/bin/tarantoolctl: Connecting to /var/run/tarantool/example.control
/bin/tarantoolctl: connected to unix/:/var/run/tarantool/example.control
unix/:/var/run/tarantool/example.control> os.exit(-1)
/bin/tarantoolctl: unix/:/var/run/tarantool/example.control: Remote host closed connection

А теперь убедимся, что systemd перезапустила его:

$ systemctl status tarantool@example|grep PID
Main PID: 5914 (tarantool)

И под конец проверим содержимое журнала загрузки:

$ journalctl -u tarantool@example -n 8
-- Logs begin at Fri 2016-01-08 12:21:53 MSK, end at Thu 2016-01-21 21:09:45 MSK. --
Jan 21 21:09:45 localhost.localdomain systemd[1]: tarantool@example.service: Unit entered failed state.
Jan 21 21:09:45 localhost.localdomain systemd[1]: tarantool@example.service: Failed with result 'exit-code'.
Jan 21 21:09:45 localhost.localdomain systemd[1]: tarantool@example.service: Service hold-off time over, scheduling restart.
Jan 21 21:09:45 localhost.localdomain systemd[1]: Stopped Tarantool Database Server.
Jan 21 21:09:45 localhost.localdomain systemd[1]: Starting Tarantool Database Server...
Jan 21 21:09:45 localhost.localdomain tarantoolctl[5910]: /usr/bin/tarantoolctl: Found example.lua in /etc/tarantool/instances.available
Jan 21 21:09:45 localhost.localdomain tarantoolctl[5910]: /usr/bin/tarantoolctl: Starting instance...
Jan 21 21:09:45 localhost.localdomain systemd[1]: Started Tarantool Database Server.

Правка настроек сервисного файла

Пожалуйста, не редактируйте файл tarantool@.service по месту, поскольку все ваши изменения будут перезаписаны при последующих обновлениях Tarantool’а. Мы рекомендуем скопировать этот файл в /etc/systemd/system и править настройки уже в копии. Либо вы можете создать поддиректорию с именем unit.d/ в директории /etc/systemd/system и положить туда drop-in файл с именем name.conf, в котором будут указаны только те настройки, которые нужно поменять. См. подробности в systemd.unit(5).

Отладка

При аварийном завершении Tarantool-сервера, coredumpctl автоматически сохраняет дампы памяти (core dumps) и трассировку стека (stack traces). Вот как работает этот механизм:

$ # !!! ВНИМАНИЕ: никогда не делайте этого
  # в условиях промышленной эксплуатации !!!
$ tarantoolctl enter example
/bin/tarantoolctl: Found example.lua in /etc/tarantool/instances.available
/bin/tarantoolctl: Connecting to /var/run/tarantool/example.control
/bin/tarantoolctl: connected to unix/:/var/run/tarantool/example.control
unix/:/var/run/tarantool/example.control> require('ffi').cast('char *', 0)[0] = 48
/bin/tarantoolctl: unix/:/var/run/tarantool/example.control: Remote host closed connection

Введем coredumpctl list /usr/bin/tarantool, чтобы получить отчет о последних аварийных завершениях Tarantool-демона:

$ coredumpctl list /usr/bin/tarantool
MTIME                            PID   UID   GID SIG PRESENT EXE
Sat 2016-01-23 15:21:24 MSK   20681  1000  1000   6   /usr/bin/tarantool
Sat 2016-01-23 15:51:56 MSK   21035   995   992   6   /usr/bin/tarantool

Чтобы получить трассировку стека и прочую полезную информацию, введем coredumpctl info <pid>:

$ coredumpctl info 21035
          PID: 21035 (tarantool)
          UID: 995 (tarantool)
          GID: 992 (tarantool)
       Signal: 6 (ABRT)
    Timestamp: Sat 2016-01-23 15:51:42 MSK (4h 36min ago)
 Command Line: tarantool example.lua <running>
   Executable: /usr/bin/tarantool
Control Group: /system.slice/system-tarantool.slice/tarantool@example.service
         Unit: tarantool@example.service
        Slice: system-tarantool.slice
      Boot ID: 7c686e2ef4dc4e3ea59122757e3067e2
   Machine ID: a4a878729c654c7093dc6693f6a8e5ee
     Hostname: localhost.localdomain
      Message: Process 21035 (tarantool) of user 995 dumped core.

               Stack trace of thread 21035:
               #0  0x00007f84993aa618 raise (libc.so.6)
               #1  0x00007f84993ac21a abort (libc.so.6)
               #2  0x0000560d0a9e9233 _ZL12sig_fatal_cbi (tarantool)
               #3  0x00007f849a211220 __restore_rt (libpthread.so.0)
               #4  0x0000560d0aaa5d9d lj_cconv_ct_ct (tarantool)
               #5  0x0000560d0aaa687f lj_cconv_ct_tv (tarantool)
               #6  0x0000560d0aaabe33 lj_cf_ffi_meta___newindex (tarantool)
               #7  0x0000560d0aaae2f7 lj_BC_FUNCC (tarantool)
               #8  0x0000560d0aa9aabd lua_pcall (tarantool)
               #9  0x0000560d0aa71400 lbox_call (tarantool)
               #10 0x0000560d0aa6ce36 lua_fiber_run_f (tarantool)
               #11 0x0000560d0a9e8d0c _ZL16fiber_cxx_invokePFiP13__va_list_tagES0_ (tarantool)
               #12 0x0000560d0aa7b255 fiber_loop (tarantool)
               #13 0x0000560d0ab38ed1 coro_init (tarantool)
               ...

Теперь введем coredumpctl -o filename.core info <pid>, чтобы сохранить дамп памяти в отдельный файл.

Далее с помощью команды coredumpctl gdb <pid> запустим отладчик gdb и подадим сохраненный дамп памяти ему на вход.

Мы очень рекомендуем установить пакет tarantool-debuginfo, чтобы сделать отладку средствами gdb более эффективной. Например:

$ dnf debuginfo-install tarantool

С помощью gdb вы можете узнать, какие еще debuginfo-пакеты нужно установить:

$ # gdb -p <pid>
...
Missing separate debuginfos, use: dnf debuginfo-install
glibc-2.22.90-26.fc24.x86_64 krb5-libs-1.14-12.fc24.x86_64
libgcc-5.3.1-3.fc24.x86_64 libgomp-5.3.1-3.fc24.x86_64
libselinux-2.4-6.fc24.x86_64 libstdc++-5.3.1-3.fc24.x86_64
libyaml-0.1.6-7.fc23.x86_64 ncurses-libs-6.0-1.20150810.fc24.x86_64
openssl-libs-1.0.2e-3.fc24.x86_64

В трассировке стека используются символические имена, даже если у вас не установлен пакет tarantool-debuginfo.

Дополнительно см. документацию по вашей Linux-системе.

Особые указания

  • Пожалуйста, не используйте tarantoolctl {start,stop,restart} для управления экземплярами, которые были запущены с помощью systemd. Но вы можете использовать tarantoolctl для запуска/остановки экземпляров в ваших локальных директориях (например, $HOME), что не требует пользовательских прав уровня ROOT.

  • Утилита tarantoolctl уже настроена так, чтобы корректно работать с systemd. Пожалуйста, не меняйте общесистемные настройки для tarantoolctl, такие как пути, настройки прав для директорий и имена пользователей, т.к. это может привести к неожиданным проблемам.

  • Поддержкой скриптов для systemd занимается команда разработки Tarantool’а (http://tarantool.org). Если у вас возникли проблемы при работе Tarantool’а с systemd, то мы просим сообщать об этом нашей команде (https://github.com/tarantool/tarantool/issues/), а не разработчикам вашего Linux-дистрибутива.

Ограничения

These limitations exist due to decisions by packagers to support systemd alongside sysvinit.

/etc/init.d/tarantool start under systemd, or systemctl start tarantool (without an @instance argument), will start only those instances which were enabled before reboot or before the last time that systemd was reloaded with systemctl daemon-reload.

(systemctl start tarantool, without an @instance argument, is provided only for interoperability with sysvinit scripts. Please use systemctl start tarantool@instance instead.)

/etc/init.d/tarantool stop under systemd, or systemctl tarantool stop (without an @instance argument), will do nothing.

Starting with Tarantool version 1.7.1.42, a new version of tarantool-common is required. (tarantool-common is a downloadable package which provides scripts to work with tarantool configuration and log files.) An attempt to upgrade tarantool-common will cause restart of all instances.

sysvinit -> systemd conversion

These instructions apply only for Debian/Ubuntu distros where both sysvinit and systemd exist.

Install new systemd-enabled packages.

#For each instancename in /etc/tarantool/instances.enabled/:
#To enable the instance to be automatically loaded by systemd:
systemctl enable tarantool@instancename

#The following command does nothing but is recommended for consistency:
/etc/init.d/tarantool stop

#Disable sysvinit-compatible wrappers:
systemctl disable tarantool; update-rc.d tarantool remove

How to write a bug report

If it’s a bug, you’re doing us a favor by taking the time to tell us about it. To make sure that we repay you with a prompt and satisfactory result, you can help us by following some simple steps. Well, usually they’re simple.

Go to the github issues site. If the problem is with the Tarantool server, go to https://github.com/tarantool/tarantool/issues. If the problem is with the Tarantool manual, go to https://github.com/tarantool/doc/issues.

Look at the current list of bugs to see whether someone has already reported this or a similar problem.

Click “New Issue”.

Fill in the Title field. Usually this should be a synopsis and contain specific unique information. For example, instead of “I can’t get certain information”, say “box.space.x:delete() didn’t report what was deleted”.

Fill in the Description field. This normally should be in English, but we accept Russian. If you think it might make a difference, include: your operating system name and version, the Tarantool name and version, and any unusual details about your machine and its configuration. Then say what you did, and what Tarantool did. Usually this involves stating all the steps needed to reproduce, and an explanation why this differs from expected behavior according to our manual, but you can skip whatever is unnecessary or obvious. If this is a feature request or if it affects a special category of user, be sure to mention that.

Optionally, click on the word “Labels” on the right of the screen, to see a list of categories. Usually the category is filled in by the the Tarantool team, but if you know it in advance you can fill it in yourself.

Click on the words “Attach files by dragging & dropping, selecting them , or pasting from the clipboard.” – but only if the Description isn’t enough to reproduce the problem. Files should not contain data that’s not needed to reproduce the problem, and should not contain anything confidential. Sometimes a log file produced with Tarantool’s logger has been useful.

Click “Submit new issue”.

Watch for a response. Usually within one or two workdays a Tarantool team member will write an acknowledgment, or some questions, or suggestions for a workaround.

Core dumps and stack traces

If a bug is severe and is hard to reproduce, the developers may ask for files which show what execution path Tarantool was following when things went wrong.

Be sure in advance that a core dump will be generated if a crash happens. In Linux, this might mean that you need to say “ulimit -c unlimited”, but there are many other reasons why a core dump will not be produced, as explained by “man 5 core”. Often core dumps are not allowed by default because core dumps can be large; however, if you make sure to get rid of them, that’s not a problem.

Be sure you know in advance what directory core dumps would be written to, and be sure that that directory is writable.

Be sure in advance that a core dump will include stack trace information. If you use a binary distribution, this is automatic. If you build from source, you will not get good information if you pass -DCMAKE_BUILD_TYPE=Release to CMake.

Tarantool will make a core dump if it receives a SIGSEGV or SIGFPE or SIGABRT or SIGQUIT signal. This is automatic if Tarantool crashes. Otherwise you can send the signal yourself to a running program, thus:
Find out the process id with “ps -A | grep tarantool”.
Kill the process with “kill -SIGSEGV [process id]”.
This is also explained in the section Generating a core file.

Core dump files can be very large and usually the Tarantool team won’t want you to send the whole file – they’ll only need a “stack trace” or “backtrace”. To produce one, say gdb -se "tarantool" -ex "bt full" -ex "thread apply all bt" --batch -c core > /tmp/tarantool_trace.txt (replacing “tarantool” with the path to the Tarantool executable, and replacing “core” with the path to the core file, and replacing “/tmp/tarantool_trace.txt” with whatever path name you prefer).

If the /tmp/tarantool_trace.txt result file is small, add it in the “Description” field or in a comment. If the result is large, upload it – follow the github instruction “Attach files ...” as stated earlier.

Occasionally you will find that tarantool_trace.txt contains output without debug symbols – the lines will contain ”??” instead of names. If this happens, check the instructions on these Tarantool wiki pages: “How to debug core dump of stripped tarantool” and How to debug core from different OS”.