Статьи

Как создать / восстановить ведомое устройство с использованием репликации GTID в MySQL 5.6

Этот пост написан  Мигелем Анхелем Ньето из MySQL Performance Blog.

MySQL 5.6 — это GA! Теперь у нас есть новые возможности для игры, и, по моему личному мнению, наиболее интересной является новая поддержка Global Transaction ID (GTID) в репликации. Этот пост не объясняет, что такое GTID и как он работает внутри, потому что есть много документов по этому поводу:

http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html

Стоит отметить, что для поддержки GTID необходимо включить log_slave_updates на подчиненном сервере и учитывать влияние на производительность.

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

Как настроить нового раба

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

gtid_executed : содержит представление набора всех транзакций, зарегистрированных в двоичном журнале
gtid_purged : содержит представление набора всех транзакций, удаленных из двоичного журнала

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


    • взять резервную копию от мастера и сохранить значение gtid_executed

    • восстановить резервную копию на ведомом устройстве и установить gtid_purged со значением gtid_executed от мастера

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

    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 |
    +---------------+------------------------------------------+

    Теперь мы берем резервную копию с mysqldump от мастера:

    # mysqldump --all-databases --single-transaction --triggers --routines --host=127.0.0.1 --port=18675 --user=msandbox --password=msandbox > dump.sql

    Он будет содержать следующую строку:

    # grep PURGED dump.sql
    SET @@GLOBAL.GTID_PURGED='9a511b7b-7059-11e2-9a24-08002762b8af:1-13';

    Поэтому во время процесса восстановления дампа на ведомом устройстве для GTID_PURGED будет установлено значение GTID_EXECUTED от ведущего.

    Теперь нам нужно восстановить дамп и запустить репликацию:

    slave1 > show global variables like 'gtid_executed';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | gtid_executed |       |
    +---------------+-------+
    
    slave1 > show global variables like 'gtid_purged';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | gtid_purged   |       |
    +---------------+-------+
    
    slave1 > slave1> source test.sql;
    [...]
    
    slave1 > show global variables like 'gtid_executed';
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | gtid_executed | 9a511b7b-7059-11e2-9a24-08002762b8af:1-13 |
    +---------------+-------------------------------------------+
    
    slave1 > show global variables like 'gtid_purged';
    +---------------+-------------------------------------------+
    | Variable_name | Value                                     |
    +---------------+-------------------------------------------+
    | gtid_purged   | 9a511b7b-7059-11e2-9a24-08002762b8af:1-13 |
    +---------------+-------------------------------------------+

    Последний шаг — настроить подчиненное устройство, используя метод автоматической настройки GTID:

    slave1 > CHANGE MASTER TO MASTER_HOST="127.0.0.1", MASTER_USER="msandbox", MASTER_PASSWORD="msandbox", MASTER_PORT=18675, MASTER_AUTO_POSITION = 1;

    Как восстановить раба плохим и быстрым способом

    Давайте представим, что наш раб не работал в течение нескольких дней, и двоичные журналы от мастера были очищены. Это ошибка, которую мы собираемся получить:

    Slave_IO_Running: No
    Slave_SQL_Running: Yes
    Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'

    Итак, давайте попробуем решить это. Сначала у нас плохой и быстрый способ, то есть указать другой GTID, который есть у мастера в двоичных журналах. Сначала мы получаем GTID_EXECUTED от мастера:

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

    И мы установили это на раба

    slave> set global GTID_EXECUTED="9a511b7b-7059-11e2-9a24-08002762b8af:1-14"
    ERROR 1238 (HY000): Variable 'gtid_executed' is a read only variable

    Ошибка! Помните, мы получаем GTID_EXECUTED от ведущего устройства и устанавливаем его как GTID_PURGED на ведомом устройстве.

    slave1 > set global GTID_PURGED="9a511b7b-7059-11e2-9a24-08002762b8af:1-14";
    ERROR 1840 (HY000): GTID_PURGED can only be set when GTID_EXECUTED is empty.

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

    slave1> reset master;
    slave1 > show global variables like 'GTID_EXECUTED';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | gtid_executed |       |
    +---------------+-------+
    slave1 > set global GTID_PURGED="9a511b7b-7059-11e2-9a24-08002762b8af:1-14";
    slave1> start slave io_thread;
    slave1> show slave status\G
    [...]
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    [...]

    Теперь, если вы не получите никаких ошибок, таких как дублирование первичного / уникального ключа, вы можете запустить pt-table-checkum и pt-table-sync .

    Как восстановить раба хорошим и медленным способом

    Хороший способ снова — mysqldump. Мы берем дамп от мастера, как мы видели раньше, и пытаемся восстановить его на рабе:

    slave1 [localhost] {msandbox} ((none)) > source test.sql;
    [...]
    ERROR 1840 (HY000): GTID_PURGED can only be set when GTID_EXECUTED is empty.
    [...]

    Wop! Важно отметить, что подобные сообщения об ошибках могут исчезать в буфере оболочки, поскольку восстановление дампа будет продолжено. Будь осторожен.

    Та же проблема снова, то же решение тоже:

    slave1> reset master;
    slave1> source test.sql;
    slave1> start slave;
    slave1> show slave status\G
    [...]
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    [...]

    Вывод

    С новым GTID нам нужно передумать. Теперь двоичный журнал и позиция — это не то, что мы должны принимать во внимание, gtid_executed и gtid_purged — наши новые друзья. Xtrabackup все еще не поддерживает это, но мы работаем над этим. Я обновлю этот пост и создам его, когда мы опубликуем версию xtrabackup с полной поддержкой GTID.