[Эта статья была написана Мигелем Анхелем Ньето]
Сочетание переменной max_allowed_packet и репликации в MySQL является распространенным источником головной боли. В двух словах, max_allowed_packet — это максимальный размер пакета сетевого протокола MySQL, который сервер может создать или прочитать. Он имеет значение по умолчанию 1 МБ (<= 5.6.5) или 4 МБ (> = 5.6.6) и максимальный размер 1 ГБ. Это добавляет некоторые ограничения в нашей среде репликации:
- Главный сервер не должен записывать события в двоичный журнал больше, чем max_allowed_packet
- Все ведомые в цепочке репликации должны иметь такой же max_allowed_packet, что и главный сервер
Иногда, даже следуя этим двум основным правилам, у нас могут возникнуть проблемы.
Например, существуют ситуации (также называемые ошибками), когда мастер записывает больше данных, чем предел max_allowed_packet, в результате чего подчиненные устройства перестают работать. Чтобы исправить это, Oracle создал новую переменную под названием slave_max_allowed_packet . Эта новая переменная конфигурации, доступная из 5.1.64, 5.5.26 и 5.6.6, переопределяет значение max_allowed_packet для подчиненных потоков. Следовательно, независимо от значения max_allowed_packet потоки ведомых будут иметь ограничение в 1 ГБ, значение по умолчанию slave_max_allowed_packet. Хороший трюк, который работает как ожидалось.
Иногда даже с этим обходным путем мы можем получить ошибку max_allowed_packet на подчиненных серверах. Это означает, что существует пакет размером более 1 ГБ, чего не должно происходить в обычной ситуации. Зачем? Обычно это вызвано повреждением двоичного журнала. Давайте посмотрим на следующий пример:
Slave перестает работать со следующим сообщением:
Last_IO_Error: Получена фатальная ошибка 1236 от мастера при чтении данных из двоичного журнала: «превышена запись в журнале событий max_allowed_packet; Увеличьте max_allowed_packet на master '
Важной частью является «получение фатальной ошибки 1236 от мастера». Мастер не может прочитать событие, которое он записал в двоичный журнал несколько секунд назад. Чтобы проверить проблему, мы можем:
- Используйте mysqlbinlog, чтобы прочитать двоичный журнал из позиции, в которой он потерпел неудачу с –start-position.
Это пример, взятый с наших форумов Percona :
# 121003 5:22:26 идентификатор сервера 1 end_log_pos 398528 # Неизвестное событие # на 398528 # 960218 6:48:44 id сервера 1813111337 end_log_pos 1835008 # Неизвестное событие ОШИБКА: Ошибка в Log_event :: read_log_event (): «Событие слишком большое», data_len: 1953066613, event_type: 8 РАЗДЕЛИТЕЛЬ; # Конец файла журнала
Проверьте размер события, 1953066613 байт. Или сообщения «Неизвестное событие». Там что-то явно не так. Другая обычная вещь для проверки — это идентификатор сервера, который иногда не соответствует реальному значению. В этом примере человек, который разместил двоичное событие журнала, подтвердил, что идентификатор сервера был неправильным.
- Проверьте основной журнал ошибок.
[ОШИБКА] Ошибка в Log_event :: read_log_event (): «Событие слишком большое», data_len: 1953066613, event_type: 8
Опять же, событие больше, чем ожидалось. Ведущий и ведомый не могут ни читать, ни записывать, поэтому решение состоит в том, чтобы пропустить это событие в ведомом устройстве и повернуть журналы на главном. Затем используйте pt-table-checkum для проверки согласованности данных.
MySQL 5.6 включает контрольные суммы репликации, чтобы избежать проблем с повреждениями журнала. Вы можете прочитать больше об этом в блоге Стефана .
Вывод
Ошибки на подчиненных серверах в отношении max_allowed_packet могут быть вызваны разными причинами. Хотя повреждение двоичного журнала не является распространенным явлением, его стоит проверить, если у вас закончились идеи.