Read_Buffer_Size Может Нарушить Репликацию Данных

Перевод последней статьи Мигель Анхель Ньето «read_buffer_size может нарушить вашу репликацию» .

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

В этом посте я расскажу о переменной read_buffer_size и о том, как эта переменная вместе с max_allowed_packet может нарушить вашу репликацию.

Допустим, у нас есть настройка репликации мастер-мастер:

max_allowed_packet = 32M read_buffer_size = 100M

Чтобы прервать репликацию, я собираюсь загрузить 4 миллиона строк с помощью LOAD DATA INFILE:

MasterA (test) > LOAD DATA INFILE '/tmp/data' INTO TABLE t; Query OK, 4510080 rows affected (26.89 sec)

Через некоторое время команда SHOW SLAVE STATUS на MasterA выдаст нам следующий результат:

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master;the first event 'mysql-bin.000002' at 74416925, the last event read from '.

/mysql-bin.000004' at 171, the last byte read from '.

/mysql-bin.000004' at 190.'

Очень странно! Мы загрузили данные в MasterA, а теперь у нас там сломана репликация и ошибка, связанная с max_allowed_packet. Следующий шаг — проверка двоичных журналов обоих мастеров: МастерА:

masterA> mysqlbinlog data/mysql-bin.000004 | grep block_len #Begin_load_query: file_id: 1 block_len: 33554432 #Append_block: file_id: 1 block_len: 33554432 #Append_block: file_id: 1 block_len: 33554432 #Append_block: file_id: 1 block_len: 4194304 #Append_block: file_id: 1 block_len: 33554432 #Append_block: file_id: 1 block_len: 10420608

Нет блока размером больше max_allowed_packet (33554432).

МастерБ:

masterB> mysqlbinlog data/mysql-bin.000004 | grep block_len #Begin_load_query: file_id: 1 block_len: 33555308 #Append_block: file_id: 1 block_len: 33555308 #Append_block: file_id: 1 block_len: 33555308 #Append_block: file_id: 1 block_len: 4191676 #Append_block: file_id: 1 block_len: 33555308 #Append_block: file_id: 1 block_len: 10419732

Заметили разницу? 33555308 больше, чем max_allowed_packet (33554432), поэтому Master2 записал некоторые блоки на 876 байт больше безопасного значения.

Затем MasterA пытается прочитать двоичный журнал с MasterB, и репликация прерывается, поскольку пакеты слишком велики.

Нет, replication_same_server_id не включен.



Какая связь между read_buffer_size и этой ошибкой?
Опять же, лучше привести пример, чем объяснять словами.

Возьмем новые значения:

max_allowed_packet = 32M read_buffer_size = 16M

Мы снова запускаем LOAD DATA INFILE, и теперь вывод на обоих серверах будет таким:

#Begin_load_query: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 16777216 #Append_block: file_id: 1 block_len: 14614912

Максимальный размер блоков данных основан на значении read_buffer_size, поэтому теперь они точно никогда не будут больше max_allowed_packet. Поэтому стоит помнить, что если значение read_buffer_size больше max_allowed_packet, то это может привести к сбою репликации при импорте данных в MySQL. Эта ошибка присутствует во всех версиях от 5.0.x до последней 5.5.25, и самый простой способ ее обойти — не устанавливать значение read_buffer_size больше, чем max_allowed_packet. Это выглядит как ошибка 30435 на самом деле до сих пор не исправлено.

И не забывайте, что большие значения read_buffer_size не улучшают производительность (об этом можно прочитать Здесь в оригинале и Здесь - перевод).

Теги: #хитрости с MySQL #MySQL

Вместе с данным постом часто просматривают: