Статьи

Отработка отказа с помощью MySQL Utilities, часть 1: mysqlrpladmin

Первоначально написано Stephane Combaudon

MySQL Utilities — это набор инструментов, предоставляемых Oracle для выполнения многих видов административных задач. Когда включена GTID-репликация, для продвижения подчиненного можно использовать 2 инструмента: mysqlrpladminи mysqlfailover. Мы рассмотрим mysqlrpladmin(версия 1.4.3) в этом посте.

Резюме

  • mysqlrpladmin может выполнять аварийное переключение / переключение вручную, когда включена GTID-репликация.
  • Вам необходимо настроить серверы с помощью --master-info-repository = TABLEили добавить --rpl-userопцию, чтобы инструмент работал правильно.
  • Проверка на ошибочные транзакции не выполняется в текущей версии GA (1.4.3), поэтому будьте особенно внимательны при ее использовании или просмотрите ошибку # 73110, чтобы увидеть, когда исправление зафиксировано.
  • Существуют некоторые ограничения, например, невозможность предварительно сконфигурировать список ведомых в файле конфигурации или невозможность проверить, что инструмент будет работать нормально, без фактического переключения при отказе или переключения.

Аварийное переключение против переключения

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

Настройка для этого теста

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

$ mysqlrpladmin --master=root@localhost:13001 --discover-slaves-login=root health
# Discovering slaves for master at localhost:13001
# Discovering slave at localhost:13002
# Found slave: localhost:13002
# Discovering slave at localhost:13003
# Found slave: localhost:13003
# Checking privileges.
#
# Replication Topology Health:
+------------+--------+---------+--------+------------+---------+
| host       | port   | role    | state  | gtid_mode  | health  |
+------------+--------+---------+--------+------------+---------+
| localhost  | 13001  | MASTER  | UP     | ON         | OK      |
| localhost  | 13002  | SLAVE   | UP     | ON         | OK      |
| localhost  | 13003  | SLAVE   | UP     | ON         | OK      |
+------------+--------+---------+--------+------------+---------+
# ...done.

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

Простой сценарий отработки отказа

Что будет делать инструмент при выполнении отработки отказа? По сути, мы дадим ему список рабов и список кандидатов, и он будет:

  • Проведите несколько проверок работоспособности
  • Выберите кандидата, чтобы стать новым мастером
  • Сделать кандидата как можно более современным, сделав его рабом всех остальных рабов
  • Настройте репликацию на всех других ведомых устройствах, чтобы они реплицировались с нового главного устройства.

После убийства мастера -9, давайте попробуем перейти на другой ресурс:

$ mysqlrpladmin --slaves=root:@localhost:13002,root:@localhost:13003 --candidates=root@localhost:13002 failover

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

Однако мы получаем ошибку:

# Checking privileges.
# Checking privileges on candidates.
ERROR: You must specify either the --rpl-user or set all slaves to use --master-info-repository=TABLE.

Сообщение об ошибке ясно, но было бы неплохо иметь такие подробности при запуске healthкоманды (возможно, предупреждение вместо ошибки). Это позволило бы вам заранее проверить, что инструмент может работать бесперебойно, а не обнаруживать в середине аварийной ситуации, что вам нужно просмотреть документацию, чтобы найти, какой параметр отсутствует.

Давайте выберем указать пользователя репликации:

$ mysqlrpladmin --slaves=root:@localhost:13002,root:@localhost:13003 --candidates=root@localhost:13002 --rpl-user=repl:repl failover
# Checking privileges.
# Checking privileges on candidates.
# Performing failover.
# Candidate slave localhost:13002 will become the new master.
# Checking slaves status (before failover).
# Preparing candidate for failover.
# Creating replication user if it does not exist.
# Stopping slaves.
# Performing STOP on all slaves.
# Switching slaves to new master.
# Disconnecting new master as slave.
# Starting slaves.
# Performing START on all slaves.
# Checking slaves for errors.
# Failover complete.
#
# Replication Topology Health:
+------------+--------+---------+--------+------------+---------+
| host       | port   | role    | state  | gtid_mode  | health  |
+------------+--------+---------+--------+------------+---------+
| localhost  | 13002  | MASTER  | UP     | ON         | OK      |
| localhost  | 13003  | SLAVE   | UP     | ON         | OK      |
+------------+--------+---------+--------+------------+---------+
# ...done.

Простой сценарий переключения

Давайте теперь перезапустим старый мастер и настроим его в качестве подчиненного нового мастера (кстати, это можно сделать с помощью mysqlreplicateдругого инструмента из MySQL Utilities). Если мы хотим продвинуть старого мастера, мы можем запустить:

$ mysqlrpladmin --master=root@localhost:13002 --new-master=root@localhost:13001 --discover-slaves-login=root --demote-master --rpl-user=repl:repl --quiet switchover
# Discovering slave at localhost:13001
# Found slave: localhost:13001
# Discovering slave at localhost:13003
# Found slave: localhost:13003
+------------+--------+---------+--------+------------+---------+
| host       | port   | role    | state  | gtid_mode  | health  |
+------------+--------+---------+--------+------------+---------+
| localhost  | 13001  | MASTER  | UP     | ON         | OK      |
| localhost  | 13002  | SLAVE   | UP     | ON         | OK      |
| localhost  | 13003  | SLAVE   | UP     | ON         | OK      |
+------------+--------+---------+--------+------------+---------+

Обратите внимание, что мастер доступен в этом случае, поэтому мы можем использовать эту discover-slaves-loginопцию. Также обратите внимание , что мы можем настроить подробность инструмента с помощью --quietили --verboseдаже войти вывод в файл с расширением --log.

Мы также --demote-masterделали старого мастера рабом нового мастера. Без этой опции старый мастер будет изолирован от других узлов.

Точки расширения

В общем, переключение / отработка отказа на уровне базы данных — это одно, но для того, чтобы приложение продолжало работать правильно, чаще всего необходимо сообщить другим компонентам приложения, что что-то изменилось.

Здесь точки расширения удобны: вы можете выполнить скрипт перед переключением / переключением с помощью --exec-beforeи после переключения / переключением с помощью --exec-after.

Например, с помощью этих простых скриптов:

# cat /usr/local/bin/check_before
#!/bin/bash
/usr/local/mysql5619/bin/mysql -uroot -S /tmp/node1.sock -Ee 'SHOW SLAVE STATUS' > /tmp/before
# cat /usr/local/bin/check_after
#!/bin/bash
/usr/local/mysql5619/bin/mysql -uroot -S /tmp/node1.sock -Ee 'SHOW SLAVE STATUS' > /tmp/after

Мы можем выполнить:

$ mysqlrpladmin --master=root@localhost:13001 --new-master=root@localhost:13002 --discover-slaves-login=root --demote-master --rpl-user=repl:repl --quiet --exec-before=/usr/local/bin/check_before --exec-after=/usr/local/bin/check_after switchover

И, глядя на / tmp / before и / tmp / after, мы видим, что наши скрипты были выполнены:

# cat /tmp/before
# cat /tmp/after
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: localhost
                  Master_User: repl
                  Master_Port: 13002
[...]

Если внешний скрипт не работает, использование -verbose может быть полезно для диагностики проблемы.

Как насчет ошибочных транзакций?

Мы уже упоминали, что ошибочные транзакции могут создать много проблем, когда новый мастер продвигается в кластере с GTID. Таким образом, вопрос: как mysqlrpladminсебя вести, когда происходит ошибочная транзакция?

Давайте создадим ошибочную транзакцию:

# On localhost:13003
mysql> CREATE DATABASE test2;
mysql> FLUSH LOGS;
mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |     69309 |
| mysql-bin.000002 |   1237667 |
| mysql-bin.000003 |       617 |
| mysql-bin.000004 |       231 |
+------------------+-----------+
mysql> PURGE BINARY LOGS TO 'mysql-bin.000004';

и давайте попробуем продвинуть localhost: 13003 в качестве нового мастера:

$ mysqlrpladmin --master=root@localhost:13001 --new-master=root@localhost:13003 --discover-slaves-login=root --demote-master --rpl-user=repl:repl --quiet switchover
[...]
+------------+--------+---------+--------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| host       | port   | role    | state  | gtid_mode  | health                                                                                                                                                                                                                                                                                              |
+------------+--------+---------+--------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| localhost  | 13003  | MASTER  | UP     | ON         | OK                                                                                                                                                                                                                                                                                                  |
| localhost  | 13001  | SLAVE   | UP     | ON         | IO thread is not running., 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.', Slave has 1 transactions behind master.  |
| localhost  | 13002  | SLAVE   | UP     | ON         | IO thread is not running., 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.', Slave has 1 transactions behind master.  |
+------------+--------+---------+--------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

К сожалению! Хотя это и предлагается в документации, инструмент не проверяет ошибочные транзакции. Это серьезная проблема, поскольку вы не можете надежно выполнить аварийное переключение / переключение с репликацией GTID, если ошибочные транзакции не обнаружены правильно.

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

Некоторые ограничения

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

  • Вы не можете использовать файл конфигурации со списком всех ведомых. Это становится скучно, когда у вас есть большое количество рабов. В таком случае вы должны написать скрипт-обертку, mysqlrpladminчтобы сгенерировать правильную команду для вас
  • Процесс выбора подчиненного устройства либо автоматический, либо зависит от порядка серверов, указанных в --candidatesопции. Это не очень сложно.
  • Было бы полезно иметь режим -dry-run, который бы проверял, что все настроено правильно, но на самом деле не происходит сбой / переключение. Это то, что MHA делает, например.

Вывод

mysqlrpladminэто очень хороший инструмент, который поможет вам выполнить аварийное переключение / переключение вручную в кластере с использованием репликации GTID. Основным предупреждением на этом этапе является неудачная проверка ошибочных транзакций, которая требует большой осторожности перед запуском инструмента.