Это сообщение от
из блога 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
установка становится неуместной, так как таблица будет всегда обновляться при каждой транзакции независимо от значения параметра. Таким образом, вы можете безопасно удалить его из файла конфигурации.
Я надеюсь, что этот пост поможет вам извлечь выгоду из этой замечательной функции!