У меня есть главный сервер и несколько подчиненных серверов, реплицирующих единую базу данных. Я использую 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, репликация снова начнет работать.
Есть идеи, что я могу с этим сделать?
Когда ведомое устройство MySQL подключается к ведущему устройству, оно запрашивает поток двоичного журнала, и ведущее устройство автономно отправляет события двоичного журнала так часто, как они происходят, без подтверждения от ведомого устройства, если вы не используете полусинхронную репликацию.
Подчиненное устройство не создает никакого трафика, кроме подтверждений низкого уровня, обрабатываемых стеком TCP. Нарушение связи (на различных уровнях стека, не ограничиваясь отключенным кабелем) может привести к разрыву соединения несколькими способами, включая разрыв соединения TCP-стеком главного устройства из-за тайм-аутов, сообщения о недоступности ICMP или брандмауэра с отслеживанием состояния. между машинами, которые «забывают» о сеансе TCP и молча отбрасывают последующие пакеты, при этом ведомое устройство спокойно сидит и ждет следующего пакета от ведущего.
Решением здесь является глобальная переменная slave_net_timeout
.
Количество секунд ожидания дополнительных данных от ведущего устройства, прежде чем ведомое устройство сочтет, что соединение разорвано, прервет чтение и попытается восстановить соединение.
Это настроено на ведомом устройстве. Когда ведомое устройство подключается к ведущему, перед запросом потока binlog, оно просит ведущее отправить события пульса, которые форматируются как события binlog и передаются в потоковом режиме, как если бы они были следующим событием в binlog ведущего, но фактически не увеличивают счетчики позиций binlog. По сути, они не требуют дополнительных затрат при нормальной работе, потому что они не отправляются, если ведущее устройство не сгенерировало новые события бинарного журнала для половины ведомого устройства. slave_net_timeout
настройка (по умолчанию; или другое значение, которое можно настроить во время CHANGE MASTER TO
), поэтому события сердцебиения на самом деле генерируются только тогда, когда трафик очень слабый ... так что, насколько я могу судить, нет никакого реального вреда при установке этого значения всего на несколько секунд.
Если ведомое устройство видит, что время ожидания истекло, оно закрывает свое соединение и повторно подключается к ведущему.
В случае удаленного шанса, что мастер не понимает, что подчиненное устройство ушло, когда подчиненное устройство повторно подключается, мастер закроет исходное соединение, потому что мастер MySQL, принимая новое подчиненное соединение, проверяет, есть ли другое подчиненное устройство с таким же server_id
уже подключен, и если да, то разрывает исходное соединение. Это, кстати, причина того, что два ведомых устройства настроены с одинаковым server_id
(неподдерживаемая конфигурация) не может успешно оставаться подключенным к одному и тому же ведущему устройству - как только один из них подключается, это приводит к отключению другого, и возникает цикл, в котором каждое ведомое устройство принудительно разрывает соединение другого.
Установка этой переменной на достаточно низкое значение в my.cnf и перезапуск ведомого устройства должны решить эту проблему.