Статьи

Репликация в MySQL 5.6: преимущества и ограничения GTID — часть 2

Это сообщение  написано Стефаном Комбоудоном в блоге MySQL Performance.

 

Основное преимущество использования идентификаторов GTID состоит в том, что их восстановление при сбое намного проще, чем при репликации на основе файлов. Мы увидим, как изменить топологию репликации при использовании репликации на основе GTID. Это покажет, где блестят GTID и где ожидаются улучшения.

Это второй пост из серии статей, посвященных GTID для MySQL 5.6. Вы можете найти первую часть здесь .

Наша цель — перейти от установки № 1 к установке № 2 на рисунке ниже, следуя различным сценариям:

repli_setup

В этих тестах все серверы работают на 127.0.0.1 с портами в диапазоне от 10000 для s0 до 10004 для s4.

Сценарий № 1: Все рабы обработали все записи

Это самый простой случай, мы сделаем s2 мастером и перенаправим репликацию на других серверах на s2. Этот сценарий может произойти, если вы хотите выполнить запланированное аварийное переключение.

С GTID все операции просты:

#For s2 (the new master), we remove its configuration as a slave
s1> stop slave;
s1> reset slave all;
# For s0
s0> change master to master_host='127.0.0.1',master_user='rsandbox',master_password='rsandbox',master_port=10001,master_auto_position=1;
s0> start slave;
# For s1, s3 and s4
mysql> stop slave;
mysql> change master to master_port=10002;
mysql> start slave;

Те из вас, кто уже выполнил эти операции с репликацией на основе файлов, знают, что это обычно очень утомительно и что правильную запись позиции файла binlog / binlog нужно делать с осторожностью, если вы не хотите прерывать репликацию или повреждать свои данные. ,

Сценарий № 2: один из рабов позади

Теперь давайте представим, что s0 потерпел крах, и что s1 не получил все записи (и, следовательно, s3 и s4 также отстают).

s2> select count(*) from t;
+----------+
| count(*) |
+----------+
|        2 |
+----------+
# s1 is behind
s1> select count(*) from t;
+----------+
| count(*) |
+----------+
|        0 |
+----------+

Можем ли мы еще использовать master_auto_position = 1? Будем надеяться, так как это одна из идей GTID: иметь для каждого события в кластере монотонно-инкрементный идентификатор для каждого события.

Обратите внимание, что это та же проблема для s0 (который будет поздно, когда он вернется) и s1, s3 и s4.

Давайте попробуем!

# For s0,s1, s3, s4
mysql> stop slave;
mysql> change master to master_port=10002;
mysql> start slave;
# And then check the number of records from the t table
s1> select count(*) from t;
+----------+
| count(*) |
+----------+
|        2 |
+----------+

Большой! Итак, еще раз, использование GTID позволяет избежать утомительной работы по поиску позиции в журнале определенного события. Единственная часть, на которую мы должны обратить внимание — это сервер, который мы выбираем для продвижения: если он не обновлен, данные могут быть потеряны или репликация может быть нарушена.

Сценарий № 3: мастер вышел из строя перед отправкой всех записей

Если двоичные журналы мастера больше не читаются, вы, вероятно, потеряете события, которые не были отправлены на подчиненные устройства (ваш последний шанс — восстановить данные с разбитого мастера, но это уже другая история). В этом случае вам придется продвигать самого современного ведомого и перенастроить других подчиненных, как мы делали выше.

Поэтому мы предположим, что мы можем прочитать двоичные журналы сбойного мастера. Первое, что нужно сделать после выбора ведомого, который будет новым мастером, — это восстановить пропущенные события с помощью mysqlbinlog.

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

s1> show slave status\G
[...]
Executed_Gtid_Set: 219be3a9-c3ae-11e2-b985-0800272864ba:1,
3d3871d1-c3ae-11e2-b986-0800272864ba:1-4

Мы можем видеть, что не очевидно знать, какое событие было последним выполненным: это 219be3a9-c3ae-11e2-b985-0800272864ba:1или нет 3d3871d1-c3ae-11e2-b986-0800272864ba:4? Столбец «Last_Executed_GTID» был бы полезен.

В нашем случае мы можем проверить, 3ec18c45-c3ae-11e2-b986-0800272864baявляется ли UUID сервера s2, а другой — из s0 (для сбоя s0 UUID сервера можно прочитать в файле auto.cnf в каталоге данных).

Таким образом , последний выполняется событие 219be3a9-c3ae-11e2-b985-0800272864ba:1. Как я могу дать команду mysqlbinlog начать чтение оттуда? К сожалению, нет --start-gtid-positionварианта или аналога. Смотрите ошибка # 68566 .

Значит ли это, что мы не можем легко восстановить данные с помощью mysqlbinlog? Конечно, есть решение, но, на мой взгляд, очень плохое: найдите файл binlog / позицию последнего выполненного события и используйте mysqlbinlog со старой доброй --start-positionопцией! Даже с GTID вы не можете полностью забыть о позиционировании реплики старого стиля.

Вывод

Переконфигурировать репликацию при использовании GTID, как правило, несложно: просто подключите подчиненное устройство к правильному главному устройству master_auto_position = 1. Это может быть даже сделано проще с mysqlfailover от MySQL Utilities (это будет тема будущего сообщения).

К сожалению, это не будет работать для каждого варианта использования, и пока это не исправлено, полезно знать о текущих ограничениях.