Percona TokuDB

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 17:12, 4 августа 2017.
(перенаправлено с «TokuDB»)
Percona TokuDB Storage Engine
Percona TokuDB.png
Разработчики: The Percona Team
Локализация: Английский
Тип ПО: MySQL движок таблиц
Лицензия: GNU General Public License v.2
Веб-сайт https://www.percona.com/

TokuDB - это высокопроизводительная подсистема хранения данных с открытым исходным кодом для MySQL и MariaDB. Это достигается путем применения фрактальных индексных деревьев. TokuDB оптимален в системах с интенсивной записью, когда требуется накапливать полученную в результате входящих запросов информацию и периодически генерировать на её основе отчёты. В качестве основных областей применения TokuDB называются конфигурации с большим числом запросов, связанных с добавлением, удалением и изменением данных, такие как социальные сети, анализ логов, рекламные сети и т.п.

Обзор

TokuDB использует фрактальные индексные деревия, которые хранят данные в отсортированном виде и позволяют осуществлять поиск и последовательный доступ за такое же время, как и B-дерево, но со вставками и удалениями, которые асимптотически быстрее, чем в B-деревьях.

Из особенностей TokuDB также можно отметить:

  • Обеспечение требований ACID к выполнению транзакций (атомарность, согласованность, изолированность, долговечность);
  • Возможность изменения хранения схемы данных на лету, без перестроения хранилища;
  • Отсутствие эффекта фрагментации индексов после длительного времени работы базы (нет необходимости пересоздавать индексы для устранения фрагментации);
  • Гибкие средства ускорения выполнения запросов через использование индексов. Поддержка "горячего" добавления и изменения индексов;
  • Поддержка создания хранилищ для терабайт данных;
  • Поддержка создания горячих бэкапов без остановки работы;
  • Поддержка репликации интенсивно поступающих потоков данных на несколько slave-серверов без отставания появления данных на slave-системах;
  • Соответствие требованиям MVCC (Multi-Version Concurrency Control) по работе в многопользовательских системах с большим числом одновременных запросов;
  • Режим быстрого восстановления после сбоя;
  • Высокая эффективность поддержания хранилищ с десятками и сотнями миллионов записей. Отсутствуют проблемы при активном удалении записей в таких хранилищах;
  • Поддержка кластерных индексов, в которых непосредственно могут сохраняться любые данные из записей;
  • По выполняемым операциям индексы Fractal Tree indexes схожи в B-Tree и отличаются главным образом более оптимальным использованием кэшей и доступа к данным на накопителях на жестких магнитных дисках, за счёт преобразования операций случайного доступа в наборы последовательных запросов. Для SSD-накопителей использование TokuDB оправдано сокращением числа операций записи.

Сравнение с InnoDB

При проведении тестов, TokuDB опережает InnoDB при добавлении больших объемов данных более чем в 10 раз (InnoDB 1,555 записей в сек, TokuDB 16,437 записей в сек), но проигрывает по степени нагрузки на CPU при выборке данных. Недостаточная эффективность выборки данных компенсируется ситуациями когда требуется произвести выборку большого числа последовательно сохранённых записей. В некоторых тестах выигрыш в скорости добавления данных достигает 80 раз. Применяемые методы сжатия данных позволяют в разы уменьшить размер базы и индексов (в 6.2 раза по сравнению с InnoDB и в 5.5 раз по сравнению с MyISAM), в некоторых ситуациях степень сжатия данных может достигать 25 раз.

Применение

В настоящее время движок TokuDB уже используется проектом Mozilla для организации работы сервиса Datazilla, занимающегося сбором информации о производительности, автоматически отправляемой браузером Firefox, при включении соответствующих настроек. Разработчики MySQL и MariaDB приветствовали решение по открытию кода TokuDB, заявив, что такой шаг будет способствовать широкому внедрению TokuDB. Более того, разработчики MariaDB уже рассматривают возможность включения TokuDB в состав MariaDB и поставки данного движка в качестве штатного компонента.

Код открыт под лицензией GPLv2. Изначально движок TokuDB развивался как проприетарный продукт, но компания Tokutek решилась на изменение бизнес-модели, которая теперь подразумевает разработку TokuDB как свободного проекта с предоставлением корпоративным заказчикам коммерческой версии TokuDB Enterprise Edition, которая отличается наличием сервиса технической поддержки, расширенными инструментами для резервного копирования и возможностью адаптации продукта под нужды заказчика.

Установка

Установка Percona Server

Все варианты установки можно посмотреть здесь. Мы будем устанавливать из apt-репозитория под Ubuntu 16.10.

  1. Получим пакеты репозитория:
    wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb
  2. Установим полученный пакет с помощью dpkg. Для этого выполним команду от суперпользователя:
    sudo dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb
  3. Обновим локальный кеш
    sudo apt-get update
  4. Теперь можно установить пакет сервера
    sudo apt-get install percona-server-server-5.7

Установка TokuDB engine

Полный гайд можно найти здесь, мы будем устанавливать TokuDB на Ubuntu 16.10. К этому моменту у нас уже должен быть установлен Percona Server.

Установка из apt репозитория

Установим TokuDB с использованием apt:

apt-get install percona-server-tokudb-5.7

Как только закончится установка мы увидим следующее сообщение:

This release of Percona Server is distributed with TokuDB storage engine.
* Run the following script to enable the TokuDB storage engine in Percona Server:
  ps_tokudb_admin --enable -u <mysql_admin_user> -p[mysql_admin_pass] [-S <socket>] [-h <host> -P <port>]
* See http://www.percona.com/doc/percona-server/5.7/tokudb/tokudb_installation.html for more installation details
* See http://www.percona.com/doc/percona-server/5.7/tokudb/tokudb_intro.html for an introduction to TokuDB

В Percona Server встроен скрипт ps_tokudb_admin, который поможет легко активировать движок TokuDB. Этот скрипт автоматически отключит Transparent huge pages, если они включены и установит и активирует TokuDB с всеми необходимыми плагинами. Нужно будет запустить этот скрипт с правами суперпользователя

ps_tokudb_admin --enable -u root -p Passw0rd
Если установка прошла успешно, мы увидим следующее сообщение:
Checking if Percona server is running with jemalloc enabled...
>> Percona server is running with jemalloc enabled.

Checking transparent huge pages status on the system...
>> Transparent huge pages are currently disabled on the system.

Checking if thp-setting=never option is already set in config file...
>> Option thp-setting=never is not set in the config file.
>> (needed only if THP is not disabled permanently on the system)

Checking TokuDB plugin status...
>> TokuDB plugin is not installed.

Adding thp-setting=never option into /etc/mysql/my.cnf
>> Successfuly added thp-setting=never option into /etc/mysql/my.cnf

Installing TokuDB engine...
>> Successfuly installed TokuDB plugin.

Включение TokuDB вручную

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

INSTALL PLUGIN tokudb SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_file_map SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_fractal_tree_info SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_fractal_tree_block_map SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_trx SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_locks SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_lock_waits SONAME 'ha_tokudb.so';
INSTALL PLUGIN tokudb_background_job_status SONAME 'ha_tokudb.so';

TokuDB будет активирован на сервере. Это можно проверить так:

mysql> SHOW ENGINES;
...
 | TokuDB | YES | Tokutek TokuDB Storage Engine with Fractal Tree(tm) Technology | YES | YES | YES |
...

Проверить корректность установки плагинов можно так:

mysql> SHOW PLUGINS;
...
| TokuDB                        | ACTIVE   | STORAGE ENGINE     | ha_tokudb.so | GPL     |
| TokuDB_file_map               | ACTIVE   | INFORMATION SCHEMA | ha_tokudb.so | GPL     |
| TokuDB_fractal_tree_info      | ACTIVE   | INFORMATION SCHEMA | ha_tokudb.so | GPL     |
| TokuDB_fractal_tree_block_map | ACTIVE   | INFORMATION SCHEMA | ha_tokudb.so | GPL     |
| TokuDB_trx                    | ACTIVE   | INFORMATION SCHEMA | ha_tokudb.so | GPL     |
| TokuDB_locks                  | ACTIVE   | INFORMATION SCHEMA | ha_tokudb.so | GPL     |
| TokuDB_lock_waits             | ACTIVE   | INFORMATION SCHEMA | ha_tokudb.so | GPL     |
| TokuDB_background_job_status  | ACTIVE   | INFORMATION SCHEMA | ha_tokudb.so | GPL     |
...

Версия TokuDB

Версию движка можно посмотреть c помощью команды:

mysql> SELECT @@tokudb_version;
+------------------+
| @@tokudb_version |
+------------------+
| 5.7.10-1rc1      |
+------------------+
1 row in set (0.00 sec)

Репликация

Репликация (от лат. replico -повторяю) — это тиражирование изменений данных с главного сервера БД на одном или нескольких зависимых серверах. Главный сервер будем называть мастером, а зависимые — репликами.

Изменения данных, происходящие на мастере, повторяются на репликах (но не наоборот). Поэтому запросы на изменение данных (INSERT, UPDATE, DELETE и т. д.) выполняются только на мастере, а запросы на чтение данных (проще говоря, SELECT) могут выполняться как на репликах, так и на мастере. Процесс репликации на одной из реплик не влияет на работу других реплик, и практически не влияет на работу мастера.

Репликация производится при помощи бинарных логов, ведущихся на мастере. В них сохраняются все запросы, приводящие (или потенциально приводящие) к изменениям в БД.

Бинлоги передаются на реплики (бинлог, скачанный с мастера, называется "relay binlog ") и сохраненные запросы выполняются, начиная с определенной позиции. Важно понимать, что при репликации передаются не сами измененные данные, а только запросы, вызывающие изменения.

Дамп

Пускай у нас есть сервер (Сер1), где уже есть база данных с записями, которую мы хотим реплицировать на другой сервер, где этой базы данных нет (Сер2). Тогда мы создадим эту БД на другой машине, а все записи восстановим с помощью дампа.

Создадим дамп tesdb на Сер1 с помощью команды:

mysqldump testdb > testdb.sql

Для этого может понадобиться соотвествующие права:

mysqldump -u root -p testdb > testdb.sql

После этого создастся файл testdb.sql, который нужно перенести на Сер2 и загрузить с помощью команды:

mysqldump testdb < testdb.sql

Теперь и на Сер2 у нас есть все записи, которые хранились в БД Сер1.

Далее мы рассмотрим настройку Master-Master и Master-Slave репликации.

Master - Master

У нас есть две машины, с установленными Percona Server и TokuDB storage engine.

  • Master1: 192.168.0.1
  • Master2: 192.168.0.2

Реплицировать мы будем базу данных testdb

Для начала создадим пользователей, от лица которых будет производиться репликация. Имя пользователя "replica" с правами "replication slave" и паролем "password":

mysql> CREATE USER 'replica'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.22 sec)
 
mysql> GRANT replication slave ON *.* TO 'replica'@'%';
Query OK, 0 rows affected (0.10 sec)

Это нужно сделать на обоих серверах. Далее нужно настроить параметры репликации в файле /etc/mysql/my.cnf

Настройка master1

Открываем файл /etc/mysql/my.cnf и вносим следующие изменения

[mysqld_safe]
#Если используется TokuDB
BINLOG_FORMAT=ROW
[mysqld]
#Уникальный идентификатор сервера
server-id = 1
 
#Логи ошибок
log_error = /var/log/mysql/mysql.err
 
#Путь к bin-логам сервера(бинлог, который ведет мастер)
log-bin = /var/lib/mysql/server-mysql-bin
log-bin-index = /var/lib/mysql/server-mysql-bin.index
 
#Путь к relay-логам слейва (бинлог, скачанный с мастера)
relay-log = /var/lib/mysql/slave-mysql-relay-bin
relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index
 
#БД, которые нужно/не нужно реплицировать
replicate-do-db = testdb
#Указывать БД, которые мы не реплицируем, не обязательно
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-ignore-db=performance_schema
 
#Не вести журнал бин-лога для БД (опционально)
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
 
#Чтобы не было конфликтов автоинкремента, говорим серверу,
#чтобы id генерировались начиная с 1-го прибавляя по 10,
# например 11, 21, 31, 41...
auto_increment_increment = 10
auto_increment_offset = 1
 
#Сохранять логи с мастера в своий бин-лог, чтобы передать слейву
log-slave-updates

Для принятие изменений нужно перезапустить mysql:

service mysql restart

Настройка master2

Настраиваем так же, как и первый, но поменяем server-id и offset:

[mysqld_safe]
#Если используется TokuDB
BINLOG_FORMAT=ROW
[mysqld]
#Уникальный идентификатор сервера
server-id = 2
 
#Логи ошибок
log_error = /var/log/mysql/mysql.err
 
#Путь к bin-логам сервера(бинлог, который ведет мастер)
log-bin = /var/lib/mysql/server-mysql-bin
log-bin-index = /var/lib/mysql/server-mysql-bin.index
 
#Путь к relay-логам слейва (бинлог, скачанный с мастера)
relay-log = /var/lib/mysql/slave-mysql-relay-bin
relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index
 
#БД, которые нужно/не нужно реплицировать
replicate-do-db = testdb
#Указывать БД, которые мы не реплицируем, не обязательно
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-ignore-db=performance_schema
 
#Не вести журнал бин-лога для БД (опционально)
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
 
#Чтобы не было конфликтов автоинкремента, говорим серверу,
#чтобы id генерировались начиная с 2-го прибавляя по 10,
# например 12, 22, 32, 42...
auto_increment_increment = 10
auto_increment_offset = 2
 
#Сохранять логи с мастера в своий бин-лог, чтобы передать слейву
log-slave-updates

Перезапустим mysql:

service mysql restart

Запуск репликации

Сначала запустим репликацию на Master1. Для этого нам нужно знать MASTER_LOG_FILE и MASTER_LOG_POS Master2 сервера. Это можно сделать так:

mysql> show master status;
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+
| File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB                                 | Executed_Gtid_Set |
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+
| server-mysql-bin.000001 |      120 |              |     |                   |
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+

Можно добавить ключ \G, тогда вывод будет выглядеть так:

mysql> show master status\G;
File: server-mysql-bin.000001
Position: 120
...

Теперь мы знаем все, что необходимо. Настраиваем репликацию:

mysql>CHANGE MASTER TO
           MASTER_HOST='192.168.0.2',
           MASTER_USER='replica',
           MASTER_PASSWORD='password',
           MASTER_LOG_FILE='server-mysql-bin.000001',
           MASTER_LOG_POS=120;

Запускаем репликацию и смотрим статус:

mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.2
                  Master_User: replica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: server-mysql-bin.000001
          Read_Master_Log_Pos: 120
               Relay_Log_File: slave-mysql-relay-bin.000002
                Relay_Log_Pos: 290
        Relay_Master_Log_File: server-mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: testdb
          Replicate_Ignore_DB: information_schema,mysql,performance_schema
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 120
              Relay_Log_Space: 469
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: 25f9f3ac-fd3b-11e4-bb77-080027ead940
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0

Со всего этого вывода нас интересуют Seconds_Behind_Master (время отставания реплики от мастера), Slave_IO_State (должно писать, что ждет новостей от мастера), Slave_IO_Running (Yes) и Slave_SQL_Running (Yes). Если репликация идет нормально, реплика будет следовать за мастером (номер лога в Master_Log_File и позиция Exec_Master_Log_Pos будут расти). Отставания реплики от мастера (Seconds_Behind_Master), должно быть нулевым, но может расти. Если же значение Slave_IO_State пусто, а Seconds_Behind_Master равно NULL, репликация не началась. У нас все хорошо, сделаем те же действия, но на Master2. Посмотрим статус Master1:

show master status;
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+
| File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB                                 | Executed_Gtid_Set |
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+
| server-mysql-bin.000005 |      120 |              |       |                   |
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+

Запустим репликацию на втором мастере:

mysql>CHANGE MASTER TO
           MASTER_HOST='192.168.0.1',
           MASTER_USER='replica',
           MASTER_PASSWORD='password',
           MASTER_LOG_FILE='server-mysql-bin.000005',
           MASTER_LOG_POS=120;
mysql>start slave;
mysql>show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.1
                  Master_User: replica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: server-mysql-bin.000005
          Read_Master_Log_Pos: 120
               Relay_Log_File: slave-mysql-relay-bin.000002
                Relay_Log_Pos: 290
        Relay_Master_Log_File: server-mysql-bin.000005
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: testdb
          Replicate_Ignore_DB: information_schema,mysql,performance_schema
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 120
              Relay_Log_Space: 469
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: f208be92-fa66-11e4-a905-08002742f2f0
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0

Тестирование репликации

Чтобы протестировать репликацию, создадим таблицу tab1 на Master1 и добавим в эту таблицу запись на Master2.

Создание таблицы:

mysql>use testdb;
mysql>CREATE TABLE tab1(str varchar(20)) engine=TokuDB;

Проверим создалась ли таблица на реплике:

mysql>use tesdb;
mysql>show tables;
+-----------------------+
|  Tables_in_testdb     |
+-----------------------+
|  tab1                 |
+-----------------------+

Теперь добавим запись с второго мастера и посмотрим работает ли репликация для первого мастера.

mysql>INSERT INTO tab1 VALUES("STR1");

Вводим команду на Master1:

mysql>SELECT * FROM tab1;
+------+
| str  |
+------+
| STR1 |
+------+

Master-Slave

У нас есть две машины с установленными Percona Server и TokuDB storage engine.

  • Master: 192.168.0.1
  • Slave: 192.168.0.3

База данных для репликации testdb.

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

mysql> CREATE USER 'replica'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.22 sec)

На мастере необходимо дать соответствующие права:

mysql> GRANT replication slave ON *.* TO 'replica'@'%';
Query OK, 0 rows affected (0.10 sec)

Настройка Master

Перейдем в файл /etc/mysql/my.cnf и пропишем настройки репликации:

[mysqld_safe]
#Если используется TokuDB
BINLOG_FORMAT=ROW
[mysqld]
#Уникальный идентификатор сервера
server-id = 1
 
#Логи ошибок
log_error = /var/log/mysql/mysql.err
 
#Путь к bin-логам сервера(бинлог, который ведет мастер)
log-bin = /var/lib/mysql/server-mysql-bin
log-bin-index = /var/lib/mysql/server-mysql-bin.index
 
#Путь к relay-логам слейва (бинлог, скачанный с мастера)
relay-log = /var/lib/mysql/slave-mysql-relay-bin
relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index
 
#БД, которые нужно/не нужно реплицировать
replicate-do-db = testdb
#Указывать БД, которые мы не реплицируем, не обязательно
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-ignore-db=performance_schema
 
#Не вести журнал бин-лога для БД (опционально)
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
 
#Чтобы не было конфликтов автоинкремента, говорим серверу,
#чтобы id генерировались начиная с 1-го прибавляя по 10,
# например 11, 21, 31, 41...
auto_increment_increment = 10
auto_increment_offset = 1
 
#Сохранять логи с мастера в своий бин-лог, чтобы передать слейву
log-slave-updates

Для принятие изменений, перезапустим mysql:

service mysql restart

Настройка Slave

Настройки Slave похожи на настройки мастера, кроме некоторых отличий:

  • Необходимо включить режим read_only
  • Slave не ведет бин-логи.
  • Нужно отключить стандартную проверку на уникальность и/или опцию read-before-write

Итого файл my.cnf должен выглядеть примерно так:

[mysqld_safe]
#Если используется TokuDB
read_only=1
#default uniqueness checking = 0
tokudb_rpl_unique_checks=0
#read-before-write
tokudb_rpl_lookup_rows=0
[mysqld]
#Уникальный идентификатор сервера
server-id = 3
 
#Логи ошибок
log_error = /var/log/mysql/mysql.err
 
#Путь к bin-логам сервера(бинлог, который ведет мастер)
log-bin = /var/lib/mysql/server-mysql-bin
log-bin-index = /var/lib/mysql/server-mysql-bin.index
 
#Путь к relay-логам слейва (бинлог, скачанный с мастера)
relay-log = /var/lib/mysql/slave-mysql-relay-bin
relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index

#Не вести журнал бин-лога для БД (опционально)
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
 
#Чтобы не было конфликтов автоинкремента, говорим серверу,
#чтобы id генерировались начиная с 3-го прибавляя по 10,
# например 13, 23, 33, 43...
auto_increment_increment = 10
auto_increment_offset = 3

Перезапустим mysql:

service mysql restart

Запуск репликации

Для запуска репликации нас нужны MASTER_LOG_FILE и MASTER_LOG_POS. На Master введем следующую команду, чтобы узнать их:

mysql> show master status;
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+
| File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB                                 | Executed_Gtid_Set |
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+
| server-mysql-bin.000006 |      120 |              |      |                   |
+-------------------------+----------+--------------+--------------------------------------------------+-------------------+

Теперь запусти репликацию на Slave:

mysql>CHANGE MASTER TO
           MASTER_HOST='192.168.0.1',
           MASTER_USER='replica',
           MASTER_PASSWORD='password',
           MASTER_LOG_FILE='server-mysql-bin.000006',
           MASTER_LOG_POS=120;

Посмотрим статус Slave:

mysql>show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.1
                  Master_User: replica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: server-mysql-bin.000006
          Read_Master_Log_Pos: 120
               Relay_Log_File: slave-mysql-relay-bin.000002
                Relay_Log_Pos: 290
        Relay_Master_Log_File: server-mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: testdb
          Replicate_Ignore_DB: information_schema,mysql,performance_schema
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 120
              Relay_Log_Space: 469
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: f208be92-fa66-11e4-a905-08002742f2f0
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0

Тестирование репликации

Теперь создадим на Master таблицу, чтобы проверить работу репликации:

USE testdb;
CREATE TABLE tab2(colum_a INT) engine=TokuDB;

Проверим появилась ли таблица на Slave:

mysql>USE testdb;
mysql>SHOW TABLES;
+-----------------------+
|  Tables_in_testdb     |
+-----------------------+
|  tab2                 |
+-----------------------+

Репликация работает. Стоить заметить, что при изменении testdb на Slave, изменения не должны происходить на Master.