Репликация MySQL с использованием GTID

Введение

В данной статье рассказано о базовых основах и принципах работы GTID с последующей практической настройкой репликации различными способами.

Репликация

По умолчанию в MySQL используется логический тип репликации Row-based с версии MySQL 5.7.7, ранее был Statement-Based Replication (SBR). Row-based является рекомендуемым типом для GTID.

Принцип работы GTID

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

8182213e-7c1e-11e2-a6e2-080027635ef5

Классическая репликация MySQL без GTID использует позицию в бинарном логе. Но благодаря GTID больше не нужно разбираться с вычислениями позиции бинлога. Из преимуществ GTID является согласованность данных, т.е. на сервере (как на мастере, так и на слейве) будет подтверждена одна и только одна транзакция с одним GTID, а любые другие транзакции, имеющие такой же UUID, будут проигнорированы. Подробную теорию можно дополнительно изучить на официальном сайте MySQL.

Использование GTID – это хорошая практика, т.к. данные между мастером и слейвом более консистентные с GTID, настройка ещё быстрее и проще.

В MySQL при использовании GTID есть две глобальные переменные, о которых необходимо знать:

  • gtid_executed – содержит набор всех транзакций из бинарного лога;
  • gtid_purged – содержит набор транзакций, которые были зафиксированы на сервере, но не содержащиеся в бинарном логе. gtid_purged является подмножеством gtid_executed.

Вышеописанные переменные получают свои значения при каждом запуске MySQL. На мастер-сервере это выглядит так:

master > show global variables like 'gtid_executed';
+---------------+-------------------------------------------+
| Variable_name | Value                                     |
+---------------+-------------------------------------------+
| gtid_executed | 9a511b7b-7059-11e2-9a24-08002762b8af:1-13 |
+---------------+-------------------------------------------+
master > show global variables like 'gtid_purged';
+---------------+------------------------------------------+
| Variable_name | Value                                    |
+---------------+------------------------------------------+
| gtid_purged   | 9a511b7b-7059-11e2-9a24-08002762b8af:1-2 |
+---------------+------------------------------------------+

Конфигурационные файлы

Для настройки репликации с использованием GTID в MYSQL в конфиге мастера достаточно прописать следующие значение:

gtid_mode=ON
log_bin=mysql-bin
log-slave-updates = 0
enforce-gtid-consistency
server_id=1
replicate-do-db = mybase
sync_binlog = 0

Ниже описание используемых обязательных директив из конфига:

  • gtid_mode=ON – собственно, включает GTID;
  • log_bin=mysql-bin – ведение бинарного лога для мастера (с него читает слейв). Когда на сервере используются GTID, и если бинарный лог не включен, при перезапуске сервера после аварийного выключения, некоторые GTID могут быть потеряны, что приведет к сбою репликации. При обычном завершении работы набор идентификаторов GTID из бинарного лога сохраняется в таблице mysql.gtid_executed;
  • enforce-gtid-consistency – обязательный параметр для GTID, который не даёт всё поломать;
  • server_id=1 идентификатор мастер сервера, цифровое значение может быть отличным от единицы в данном примере;

Также присутствуют необязательные директивы, но пару слов можно сказать и про них:

  • log-slave-updates = 0 – необходим при использовании схемы А -> Б -> C, где А – гл. сервер для Б, а Б – гл. сервер для С, т.е. “гирляндная” или последовательная схема. Для случаев, когда данные от мастера пишутся в отдельный бинлог реплики для использования реплики в качестве мастера для другой реплики. Редкий случай;
    sync_binlog = 0 – используется для синхронизации всех транзакций с двоичным файлом. По факту повышает надёжность транзакций для слейва при отказе ОС в случае сбоя. А также сильно влияет на производительность I\O хранилища, поэтому можно либо его отключить и положиться на надёжность отказоустойчивости системы, или же включить при наличии скоростного хранилища. В общем, использовать или нет – зависит от требований. Например, при установке sync_binlog=1 для БД Битрикс24, попугаи в тестах производительности на чтение\запись в БД могут заметно уменьшиться.

На слейве использование log_bin=mysql-bin вовсе не обязательно, т.к. идентификаторы GTID бинлога хранятся в таблице mysql.gtid_executed мастера – слейв будет читать их оттуда.

  • Для слейв-сервера конфигурационный файл выглядит так:
server-id=2
gtid_mode=ON
enforce-gtid-consistency

Настройка репликации с mysqldump

При создании дампа БД мастер-сервера с использованием mysqldump, необходимые значения GTID для слейва уже будут содержаться в дампе. Это параметр gtid_purged, который является gtid_executed с мастера. После восстановления дампа на слейве, переменная gtid_executed будет равна gtid_purged.

При запуске репликации слейв отправит мастеру диапазон GTID, которые он выполнил у себя, а мастер отправит в ответ все отсутствующие транзакции, которых нет на слейве. Таким образом можно настраивать репликацию на работающей базе (снимать копию), не останавливая запись с помощью переменной read_only=1, но очень не желательно!

При необходимости снять дамп с работающей базы, нужно использовать ключ –single-transaction, который позволяет не блокировать таблицы на момент создания дампа, но при выполнении операторов вида ALTER TABLE, DROP и т.п., которые выполняют изменения, данные в дампе могут оказаться поврежденными.

Как правило, на небольших базах допустимо использовать –single-transaction при снятии дампа. А вот на более объемных, где часто совершается запись или изменения, рекомендуется сначала выполнить блокировку таблиц на запись с помощью set global read_only=1, а потом уже выполнять снятие дампа. Но такой вариант будет очень долгий, поэтому в следующем разделе будет рассказано про Percona XtraBackup.

  • После получения дампа через mysqldump внутри него должно быть следующее:
grep -i purged dump.sql
SET @@GLOBAL.GTID_PURGED='9a511b7b-7059-11e2-9a24-08002762b8af:1-13'; # значение gtid_executed с мастера

У mysqldump есть важный параметр –set-gtid-purged, который позволяет управлять информацией глобальных идентификаторов транзакций (GTID), записанной в файл дампа, указывая, добавлять ли оператор SET @@ global.gtid_purged в вывод дампа. По умолчанию, значение этого флага auto, т.е. если GTID включен, то gtid_purged копируется, и наоборот.

При создании дампа для его последующей распаковки на реплике лучше всегда указывать явно флаг –set-gtid-purged=ON

Итого, чтобы правильно снять дамп через mysqldump с работающего мастера для настройки реплики необходимо:

  1. Перевести базу в read only – самый правильный вариант;
  2. Выполнить команду mysqldump --single-transaction --set-gtid-purged=ON db_name > db_name.sql
  • После чего необходимо создать пользователя на мастере для выполнения репликация (лучше всего отдельного). С данным пользователем слейв будет подключаться к мастеру:
master> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'slave_ip' IDENTIFIED BY 'Strong_pass!';
  • Важный момент! Необходимо убедиться, что слейв чистый, т.е. очищен от всех GTID. Для этого нужно на слейве выполнить следующее:
slave> reset master;

Согласно документации, reset slave при использовании GTID не меняет значение gtid_executed или gtid_purged, поэтому команда reset master на слейве – это не ошибка, а необходимость, чтобы убедиться, что слейв чистый и готов к настройке реплики.

И запускать репликацию со слейва привычным способом, как и ранее с позицией бинлога, но позиция указывается автоматически:

slave> CHANGE MASTER TO
    MASTER_HOST='master_ip',
    MASTER_PORT=3306,
    MASTER_USER='slave_user',
    MASTER_PASSWORD='Strong_pass!',
    MASTER_AUTO_POSITION=1;

slave> start slave;
slave> show slave status\G

Настройка репликации с Percona XtraBackup

При малых объемах БД и необходимости настройки реплики, легко и просто использовать mysqldump. Но когда объем БД за 10 Гб и более, то распаковка дампа может занять уже продолжительное время. Поэтому логичнее использовать инструмент XtraBackup от Percona. Он позволяет снимать копию с базы данных в момент её работы, используя возможности движка InnoDB.

Все транзакции, осуществленные в момент снятия копии, скапливаются в отдельном логе, который XtraBackup читает по ходу дела. После завершения бэкапа, XtraBackup применяет накопленные транзакции на снятую копию. Процесс выходит очень быстрым и позволяет переносить большие объемы данных.

Этот же инструмент можно использовать и при настройке репликации Master-Slave с GTID. XtraBackup поддерживает GTID с версии 2.1.0. Для работы с MySQL 5.7 необходима версия 2.4.

Процесс подготовки мастера и слейва ничем не отличается от ранее описанного при использовании XtraBackup. Необходимо также подготовить конфиг, указав использование GTID и ID сервера, а также создать пользователя для репликации, чтобы была возможность подключения со слейва.

На слейве параметр innodb_log_file_size должен быть того же размера, что и на мастере!

При работе с XtraBackup, все значения для подключения к MySQL берутся из конфигов.

  • Для снятия полной копии всей БД и размещения её по пути /mnt/share необходимо выполнить следующую команду:
xtrabackup --backup --target-dir=/mnt/share

Пофайловая копия будет создана достаточно быстро. Скорость зависит от хранилища. Например, база объемом 60 Гб скопировалась за меньше, чем за 10 минут.

  • Теперь необходимо выполнить подготовку бэкапа из /mnt/share, чтобы применились транзакции, выполненные в процессе снятия копии:
xtrabackup --prepare --target-dir=/mnt/share
  • Подготовленную копию теперь необходимо восстановить на слейве. Для этого демон mysql слейва должен быть остановлен, а директория data_dir быть пуста:
systemctl stop mysqld
mv $MYSQL_DATA/data $MYSQL_DATA/data.old
mkdir $MYSQL_DATA/data

Переместить копию с мастера на слейв можно любым удобным способом.

Для более быстрого переноса снятой копии с мастера на слейв, можно настроить NFS-шару на мастере. Далее там же снять копию по пути шары, выполнить подготовку, а уже на слейве выполнять восстановление. Таким образом не нужно будет лишний раз гонять файлы через rsync.

  • Выполнить восстановление копии мастера, находящейся по пути /mnt/u01/share, в целевую директорию data_dir, значение которой будет взято из конфига:
xtrabackup --copy-back --target-dir=/mnt/u01/share

Под капотом команды выше происходит полное копирование всех файлов из data_dir мастера в data_dir слейва. Необходимо обратить внимание, что все файлы ib* должны быть одного размера, как на мастере, так и на слейве, а также присутствовать в принципе в каталоге data_dir слейва. В противном случае может возникнуть ошибка “Table NAME doesn’t exist“, хотя по факту таблица будет существовать.

  • Так как каталог под данные MySQL создавался руками, необходимо выдать корректные права и запустить БД:
chown -R mysql:mysql /mnt/u01/mysql
systemctl start mysqld
  • До текущего момента процесс подготовки копии был стандартный. Копия снята, слейв запущен. Но теперь необходимо выполнить подготовку GTID для последующей настройки репликации. При снятии копии, на мастере создался файл xtrabackup_binlog_info, в котором указано значение GTID последней транзакции в данной копии. Это значение необходимо импортировать на слейв. Вывод будет следующий:
cat xtrabackup_binlog_info

mysql-bin.000027	191		8fd64058-edd8-11ea-a090-0242ac120002:1-26703081

На слейве установить значение GTID из файла xtrabackup_binlog_info для переменной GTID_PURGED:

SET GLOBAL GTID_PURGED="8fd64058-edd8-11ea-a090-0242ac120002:1-26703081";
  • И далее выполнить стандартную настройку репликации, подключаясь к мастеру с использованием GTID:
CHANGE MASTER TO
    -> MASTER_HOST='MASTER_IP',
    -> MASTER_PORT=3306,
    -> MASTER_USER='slave_user',		 
    -> MASTER_PASSWORD='Strong_pass!',
    -> MASTER_AUTO_POSITION = 1;
START SLAVE;

В данном случае по сути было выполнено тоже самое, что и через mysqldump, но с помощью XtraBackup. А значение GTID_PURGED, которое хранится обычно в дампе, было создано вручную – это единственный нюанс, который нужно учесть.

Заключение

В статье были рассмотрены теоретические сведения о работе GTID и настройке репликации различными способами. Резюмируя, ещё раз подчеркну, что для малых БД подойдет mysqldump, а для более больших проектов уже XtraBackup. Каждый инструмент удобен по-своему и можно применять в зависимости от ситуации.

Используемые источники

Понравилась статья? Поделиться с друзьями:
Комментарии: 6
  1. Алекс

    А откуда информация, что “innodb_log_file_size должен быть того же размера, что и на мастере” ? Не нашел такого ни в одной доке… А если у меня слейв и мастер в разы отличаются объемом памяти ?

    1. admin (автор)

      Да, вы правы, такого требования в доке нет. Не помню, откуда я это взял, скорее всего делал просто по аналогии: и мастер и слейв, т.к. обычно в моём случае они полностью идентичны по ресурсам.

  2. Аноним

    Спасибо за статью, очень удобно использовать как шпаргалку. Изложено довольно кратко, но вся важная инфа присутствует.

    1. admin (автор)

      Рад, что кому-то это пригодилось :)

  3. Роман

    Хорошая статья, спасибо. Уловил наконец некоторые вещи, которые в официальной документации невнятно описаны.

    1. admin (автор)

      Рад, что вам это помогло :)

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: