Репликация MySQL зависает после того, как ведомый переходит в автономный режим и снова подключается

У меня есть главный сервер и несколько подчиненных серверов, реплицирующих одну базу данных. Я использую в MySQL 5.0 в SLES 11. Во время тестирования отказоустойчивости я обнаружил, что, когда сетевое соединение подчиненного устройства (кабель отключен), а затем восстановлен, репликация зависает. Это не показывает ошибок, и ведомый, кажется, работает, но Read_Master_Log_Pos а также Exec_Master_Log_Pos значения не совпадают с позицией журнала на главном сервере.

Slave_IO_State "Ожидание, когда мастер отправит событие".

Slave_IO_Running а также Slave_SQL_Running значения оба "Да".

Master_Log_File а также Relay_Master_Log_File матч.

Если я остановлюсь и запусту ведомый или перезапущу демон mysql, репликация снова начнет работать.

Любые идеи о том, что я могу сделать по этому поводу?

1 ответ

Решение

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

Ведомый не генерирует никакого трафика, кроме подтверждений низкого уровня, обрабатываемых стеком TCP. Прерывание соединения (на разных уровнях стека, не ограничиваясь отключенным кабелем) может привести к разрыву соединения несколькими способами, включая разрыв TCP-стека в главном устройстве из-за тайм-аутов, сообщения ICMP о недоступности или брандмауэра с состоянием между машинами, "забывающими" о сеансе TCP и молча отбрасывающими последующие пакеты, когда ведомое устройство тихо сидит и ждет, когда следующий пакет придет от мастера.

Решением здесь является глобальная переменная slave_net_timeout,

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

Это настроено на раб. Когда ведомое устройство подключается к главному устройству, перед запросом потока binlog оно просит ведущее устройство отправить события контрольного сигнала, которые отформатированы как события binlog и передаются в потоковом режиме, как если бы они были следующим событием в binlog главного устройства, но фактически не увеличивают счетчики положения бинлога. Они, по сути, равны нулю в обычной работе, потому что они не отправляются, если мастер не генерирует новых событий binlog для половины подчиненного slave_net_timeout настройка (по умолчанию; или другое значение, которое вы можете настроить во время CHANGE MASTER TO), поэтому события сердцебиения на самом деле генерируются только при очень слабом трафике... поэтому, насколько я могу судить, при установке этого значения всего несколько секунд не причиняет никакого реального вреда.

Если ведомое устройство видит истечение времени ожидания, оно закрывает свое соединение и снова подключается к ведущему.

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

Установка этой переменной в my.cnf с подходящим низким значением и перезапуск ведомого устройства должны исправить эту проблему.

Другие вопросы по тегам