Практические задания по libslave | Tarantool
Документация на русском языке
поддерживается сообществом
Примеры и руководства More guides Практические задания по libslave

Практические задания по libslave

libslave представляет собой библиотеку C++ для считывания изменений данных, внесенных с помощью MySQL, а также – опционально – для записи их в базу данных Tarantool. Она выступает в качестве ведомого в схеме репликации. Сервер MySQL записывает информацию об изменении данных в бинарный журнал и передает ее на любой клиент, который запрашивает: «Хочу увидеть всю информацию, начиная с этого файла и этой записи, безостановочно». Таким образом, библиотека libslave, прежде всего, используется для создания реплик базы данных Tarantool (намного быстрее, чем используя традиционный ведомый сервер MySQL) и для отслеживания изменений данных, чтобы они были пригодны для поиска.

Здесь мы не будем подробно рассматривать библиотеку – информация есть в документации по API. Мы лишь дадим упражнение: минимальная программа с использованием библиотеки.

Примечание

Используйте тестовый сервер. Не используйте боевой сервер.

ШАГ 1: Убедитесь в наличии следующего:

  • последняя версия Linux (например, Ubuntu версии 14.04 не подойдет),

  • сервер MySQL версии 5.6 или 5.7 (MariaDB не подойдет),

  • пакет программ для разработки клиента MySQL. Например, на Ubuntu можно загрузить его с помощью следующей команды:

    $ sudo apt-get install mysql-client-core-5.7
    

ШАГ 2: Установите libslave.

Рекомендуется источник по ссылке https://github.com/tarantool/libslave/. Загрузки включают в себя только исходный код.

$ sudo apt-get install libboost-all-dev
$ cd ~
$ git clone https://github.com/tarantool/libslave.git tarantool-libslave
$ cd tarantool-libslave
$ git submodule init
$ git submodule update
$ cmake .
$ make

Если система выдаст сообщение с ошибкой со словом «vector», отредактируйте field.h, добавив следующую строку:

#include <vector>

ШАГ 3: Запустите сервер MySQL. В командной строке добавьте соответствующие коммутаторы для выполнения репликации. Например:

$ mysqld --log-bin=mysql-bin --server-id=1

ШАГ 4: Для целей данного упражнения, предполагаем, что у вас есть:

  • пользователь «root» с паролем «root» с правами,
  • тестовая база данных «test» с тестовой таблицей под названием «test»,
  • бинарный журнал под названием «mysql-bin»,
  • сервер с идентификатором 1.

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

ШАГ 5: Обратите внимание на программу:

#include <unistd.h>
#include <iostream>
#include <sstream>
#include "Slave.h"
#include "DefaultExtState.h"

slave::Slave* sl = NULL;

void callback(const slave::RecordSet& event) {
    slave::Position sBinlogPos = sl->getLastBinlogPos();
    switch (event.type_event) {
    case slave::RecordSet::Update: std::cout << "UPDATE" << "\n"; break;
    case slave::RecordSet::Delete: std::cout << "DELETE" << "\n"; break;
    case slave::RecordSet::Write:  std::cout << "INSERT" << "\n"; break;
    default: break;
    }
}

bool isStopping()
{
    return 0;
}

int main(int argc, char** argv)
{
    slave::MasterInfo masterinfo;
    slave::Position position("mysql-bin", 0);
    masterinfo.conn_options.mysql_host = "127.0.0.1";
    masterinfo.conn_options.mysql_port = 3306;
    masterinfo.conn_options.mysql_user = "root";
    masterinfo.conn_options.mysql_pass = "root";
    bool error = false;
    try {
        slave::DefaultExtState sDefExtState;
        slave::Slave slave(masterinfo, sDefExtState);
        sl = &slave;
        sDefExtState.setMasterPosition(position);
        slave.setCallback("test", "test", callback);
        slave.init();
        slave.createDatabaseStructure();
        try {
            slave.get_remote_binlog(isStopping);
        } catch (std::exception& ex) {
            std::cout << "Error reading: " << ex.what() << std::endl;
            error = true;
        }
    } catch (std::exception& ex) {
        std::cout << "Error initializing: " << ex.what() << std::endl;
        error = true;
    }
    return 0;
}

Всё лишнее почистили, чтобы можно было ясно увидеть, как это работает. В начале функции main() есть некоторые настройки, используемые для установки соединения – хост, порт, пользователь, пароль. Затем есть вызов инициализации с именем файла бинарного журнала = «mysql-bin». Обратите особое внимание на оператор setCallback, который передает имя базы данных = «test», имя таблицы = «test» и адрес функции обратного вызова = callback. Программа войдет в цикл и будет вызывать эту функцию обратного вызова. Посмотрите, как на ранних этапах программы функция обратного вызова выводит «UPDATE», «DELETE» или «INSERT» в зависимости от переданных данных.

ШАГ 5: Поместите программу в директорию tarantool-libslave и назовите ее example.cpp.

ШАГ 6: Выполните компиляцию и сборку:

$ g++ -I/tarantool-libslave/include example.cpp -o example libslave_a.a -ldl -lpthread

Примечание

Замените tarantool-libslave/include на полное имя директории.

Обратите внимание, что имя статической библиотеки – libslave_a.a, а не libslave.a.

ШАГ 7: Выполните:

$ ./example

Результат нет – программа в цикле ожидает, пока сервер MySQL запишет данные в бинарный журнал репликации.

ШАГ 8: Запустите клиентскую программу MySQL – подойдет любая клиентская программа. Введите следующие операторы:

USE test
INSERT INTO test VALUES ('A');
INSERT INTO test VALUES ('B');
DELETE FROM test;

Проверьте, что происходит в выводе программы example.cpp – отображается следующее:

INSERT
INSERT
DELETE
DELETE

Репликация является построчной, поэтому видим DELETE два раза – потому что есть две строки.

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

  • можно собрать библиотеку, а
  • программы, которые используют библиотеку, могут получить доступ ко всему, что сохраняет сервер MySQL.

Более подробную информацию и примеры использования см. ниже:

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