Репликация 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. Каждый инструмент удобен по-своему и можно применять в зависимости от ситуации.

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

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

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