Статьи

Включение отказоустойчивых ведомых с MySQL 5.6

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

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

Короче говоря

1. Остановите MySQL на ведомом
2. Добавьте relay_log_info_repository = TABLEи relay_log_recovery = ONв my.cnf
3. Перезапустите MySQL и расслабьтесь

Гори Детали

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

На ведомом устройстве репликация включает два потока: поток ввода-вывода, который копирует двоичный журнал мастера в локальную копию, называемую журналом ретрансляции, и поток SQL, который затем выполняет запросы, записанные в журнале ретрансляции. Текущая позиция каждого потока сохраняется в файле: master.infoдля потока ввода-вывода и relay-log.infoдля потока SQL.

Все идет нормально. Первая проблема заключается в том, что эти файлы не синхронизируются на диск каждый раз, когда они записываются; всякий раз, когда происходит сбой, сохраненные позиции, вероятно, будут неправильными. В MySQL 5.5 есть исправление: вы можете set sync_master_info = 1и sync_relay_log_info = 1убедиться, что оба файла записываются и синхронизируются на диск после каждой транзакции. Конечно, синхронизация не бесплатна, но если у вас есть кэш обратной записи, эти настройки могут быть полезны.

Но подождите, даже с, sync_master_info = 1и sync_relay_info = 1могут случиться плохие вещи. Причина в том, что информация о репликации записывается после совершения транзакции. Таким образом, если происходит сбой после фиксации транзакции и до обновления информации о репликации, информация о репликации будет неверной, когда сервер перезапустится и транзакция может быть выполнена дважды. Эффект будет зависеть от транзакции; Репликация может все еще работать нормально, она может быть повреждена, или несоответствия могут даже создаваться без вывода сообщений.

MySQL 5.6 решает эту проблему, позволяя нам хранить информацию репликации в таблицах вместо файлов (а mysql.slave_relay_log_infoтаблица создается , когда relay_log_info_repository = TABLEи mysql.slave_master_infoтаблица создается с master_info_repository = TABLE). Идея проста: мы можем включить обновление информации о репликации внутри транзакции, убедившись, что она всегда синхронизирована с данными.

В псевдокоде вместо:

START TRANSACTION;
-- Statement 1
-- ...
-- Statement N
COMMIT;
-- Update replication info files

Сервер теперь ведет себя так, как если бы мы имели:

START TRANSACTION;
-- Statement 1
-- ...
-- Statement N
-- Update replication info
COMMIT;

К сожалению, это не так просто, как может показаться. Для потока SQL это работает хорошо, потому что сервер может обновлять slave_relay_info_infoтаблицу одновременно с фиксацией транзакции. Однако для потока ввода-вывода обновление таблицы не связано ни с каким выполнением транзакции, так как сервер может знать, когда обновлять таблицу?

Ответ: это контролируется sync_master_info. По умолчанию установлено значение 10000, что означает, что позиция потока ввода-вывода обновляется только через каждые 10000 транзакций. Это явно нехорошо, чтобы раб был безопасен при столкновении. Одним из решений является установка sync_master_info = 1, но, как я уже говорил, это может повлиять на производительность (вот почему 1 не является настройкой по умолчанию).

Однако есть более элегантное решение — использование relay_log_recovery = ON, которое потребует перезагрузки MySQL. Этот параметр гарантирует, что при запуске сервера позиция для потока ввода-вывода восстанавливается из slave_relay_log_infoтаблицы, которая всегда актуальна. Таким образом, вам даже не нужно хранить информацию о потоках ввода / вывода в таблице, чтобы ведомое устройство было защищено от сбоев. Другими словами, настройка master_info_repository = TABLEне требуется.

В качестве последней боковой ноты, один раз relay_log_info_repository = TABLE, то sync_relay_log_infoустановка становится неуместной, так как таблица будет всегда обновляться при каждой транзакции независимо от значения параметра. Таким образом, вы можете безопасно удалить его из файла конфигурации.

Я надеюсь, что этот пост поможет вам извлечь выгоду из этой замечательной функции!