Статьи

Аварийное переключение с помощью утилит MySQL: часть 2 – mysqlfailover

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

В предыдущем посте этой серии мы увидели, как вы можете использовать mysqlrpladminдля ручного переключения / переключения при включении репликации GTID в MySQL 5.6. Теперь мы рассмотрим mysqlfailover(версия 1.4.3) еще один инструмент из MySQL Utilities, который можно использовать для автоматического переключения при сбое.

Резюме

  • mysqlfailover может выполнить автоматическое переключение при сбое, если включена репликация GTID в MySQL 5.6.
  • Все рабы должны использовать --master-info-repository=TABLE.
  • Узел мониторинга — это единственная точка отказа: не забывайте следить за ним!
  • Обнаружение ошибочных транзакций работает хорошо, но вы должны использовать --pedanticопцию, чтобы гарантировать, что отказоустойчивость никогда не произойдет, если есть ошибочная транзакция.
  • Есть несколько ограничений, таких как невозможность аварийного переключения только один раз или чрезмерная загрузка ЦП, но они, вероятно, не являются демонстраторами для большинства установок.

Настроить

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

$ mysqlfailover --master=root@localhost:13001 --discover-slaves-login=root health
[...]
MySQL Replication Failover Utility
Failover Mode = auto     Next Interval = Tue Jul  1 10:01:22 2014
Master Information
------------------
Binary Log File   Position  Binlog_Do_DB  Binlog_Ignore_DB
mysql-bin.000003  700
GTID Executed Set
a9a396c6-00f3-11e4-8e66-9cebe8067a3f:1-3
Replication Health Status
+------------+--------+---------+--------+------------+---------+
| 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      |
+------------+--------+---------+--------+------------+---------+

Обратите внимание, что --master-info-repository=TABLEнеобходимо настроить все ведомые устройства, иначе инструмент выйдет с сообщением об ошибке:

2014-07-01 10:18:55 AM CRITICAL Failover requires --master-info-repository=TABLE for all slaves.
ERROR: Failover requires --master-info-repository=TABLE for all slaves.

Отказоустойчивость

Вы можете использовать 2 команды для запуска автоматического перехода на другой ресурс:

  • auto: инструмент пытается найти кандидата в списке серверов, указанных с помощью --candidates, и, если в этом списке не найдено ни одного хорошего сервера, он проверит других подчиненных, чтобы определить, может ли быть хорошим кандидатом. Это команда по умолчанию
  • elect: аналогично auto, но если в списке кандидатов не найдено ни одного хорошего кандидата, другие ведомые не будут проверены, и инструмент завершит работу с ошибкой.

Давайте начнем инструмент с auto:

$ mysqlfailover --master=root@localhost:13001 --discover-slaves-login=root auto

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

Затем давайте убьем -9 мастера, чтобы посмотреть, что произойдет, когда мастер будет обнаружен как выключенный:

Failed to reconnect to the master after 3 attemps.
Failover starting in 'auto' mode...
# 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.
# Discovering slaves for master at localhost:13002
Failover console will restart in 5 seconds.
MySQL Replication Failover Utility
Failover Mode = auto     Next Interval = Tue Jul  1 10:59:47 2014
Master Information
------------------
Binary Log File   Position  Binlog_Do_DB  Binlog_Ignore_DB
mysql-bin.000005  191
GTID Executed Set
a9a396c6-00f3-11e4-8e66-9cebe8067a3f:1-3
Replication Health Status
+------------+--------+---------+--------+------------+---------+
| host       | port   | role    | state  | gtid_mode  | health  |
+------------+--------+---------+--------+------------+---------+
| localhost  | 13002  | MASTER  | UP     | ON         | OK      |
| localhost  | 13003  | SLAVE   | UP     | ON         | OK      |
+------------+--------+---------+--------+------------+---------+

Выглядит неплохо! Затем инструмент готов к переключению на другое ведомое устройство, если новый мастер становится недоступным.

Вы также можете запускать пользовательские скрипты в нескольких точках исполнения с --exec-before, --exec-after, --exec-fail-check, --exec-post-failoverвариантами.

Однако было бы здорово иметь --failover-and-exitвозможность избежать перебоя: инструмент обнаружит отказ главного устройства, активирует одного из подчиненных, перенастроит репликацию и затем завершит работу (это, например, то, что делает MHA).

Регистрация инструмента

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

mysql> SELECT * FROM mysql.failover_console;
+-----------+-------+
| host      | port  |
+-----------+-------+
| localhost | 13001 |
+-----------+-------+

Это хорошо, поскольку позволяет избежать запуска нескольких экземпляров mysqlfailoverдля мониторинга одного и того же мастера. Если мы попробуем, это то, что мы получаем:

$ mysqlfailover --master=root@localhost:13001 --discover-slaves-login=root auto
[...]
Multiple instances of failover console found for master localhost:13001.
If this is an error, restart the console with --force.
Failover mode changed to 'FAIL' for this instance.
Console will start in 10 seconds..........starting Console.

С помощью этой failкоманды вы mysqlfailoverбудете следить за работоспособностью репликации и завершать работу в случае сбоя главного устройства, фактически не выполняя отработки отказа.

Работает в фоновом режиме

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

$ mysqlfailover --master=root@localhost:13001 --discover-slaves-login=root auto --daemon=start --log=/var/log/mysqlfailover.log

и это можно остановить с помощью:

$ mysqlfailover --daemon=stop

Ошибочные транзакции

Если мы создадим ошибочную транзакцию на одном из ведомых, она будет обнаружена:

MySQL Replication Failover Utility
Failover Mode = auto     Next Interval = Tue Jul  1 16:29:44 2014
[...]
WARNING: Errant transaction(s) found on slave(s).
Replication Health Status
[...]

Однако это не предотвращает отработки отказа! Вы должны использовать --pedantic:

$ mysqlfailover --master=root@localhost:13001 --discover-slaves-login=root --pedantic auto
[...]
# WARNING: Errant transaction(s) found on slave(s).
#  - For slave 'localhost@13003': db906eee-012d-11e4-8fe1-9cebe8067a3f:1
2014-07-01 16:44:49 PM CRITICAL Errant transaction(s) found on slave(s). Note: If you want to ignore this issue, please do not use the --pedantic option.
ERROR: Errant transaction(s) found on slave(s). Note: If you want to ignore this issue, please do not use the --pedantic option.

Ограничения

  • Например mysqlrpladmin, процесс выбора рабов не очень сложен и не может быть отрегулирован.
  • Сервер, на котором mysqlfailoverработает, является единственной точкой отказа.
  • Чрезмерное использование процессора: когда он запущен, mysqlfailoverзагружается одно ядро. Это довольно удивительно.

Вывод

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