Версия:

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

Практические задания по 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::Slave::binlog_pos_t sBinlogPos = sl->getLastBinlog();
            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;
            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.setMasterLogNamePos("mysql-bin", 0);
                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.

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