Репликация Mysql GTID перестала работать

Я установил репликацию mysql gtid между master и slave. Интересно то, что я обнаружил, что репликация перестала работать через несколько минут, и мне пришлось использовать остановить подчиненное устройство и запустить подчиненное устройство , чтобы перезапустить репликацию mysql. Может ли кто-нибудь сказать мне, что вызывает эту проблему?

сменить ведущего на ведомом:

mysql> change master to
                -> master_host = 'master.com',
                -> master_user = 'replica',
                -> master_password = 'password',
                -> master_port = 3306,
                -> MASTER_CONNECT_RETRY = 5,
                -> MASTER_RETRY_COUNT = 0,
                -> MASTER_AUTO_POSITION=1;

Главный конфигурационный файл:

[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir         = /data/mysql_data
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking

binlog-format   = MIXED

interactive_timeout=180
wait_timeout=180

key_buffer      = 16M
max_allowed_packet  = 16M
thread_stack        = 192K
thread_cache_size       = 8

myisam-recover         = BACKUP
max_connections        = 300

query_cache_limit   = 1M
query_cache_size        = 16M

general_log             = 1
log_error = /var/log/mysql/error.log
server-id       = 1
log_bin         = /var/log/mysql/mysql-bin.log
log_bin_trust_function_creators = 1
log-slave-updates   = true

# enable GTID
gtid-mode = on
enforce-gtid-consistency = true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
binlog-checksum=CRC32
master-verify-checksum=1

expire_logs_days    = 10
max_binlog_size     = 100M

Подчиненный конфигурация:

[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /data/mysql_data
tmpdir         = /data/mysql_data/tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking

binlog-format   = MIXED

interactive_timeout=180
wait_timeout=180

key_buffer              = 16M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
max_connections        = 100

query_cache_limit       = 1M
query_cache_size        = 16M

general_log             = 1
log_error = /var/log/mysql/error.log
server-id               = 2

log_bin                 = /var/log/mysql/mysql-bin.log
log_bin_trust_function_creators = 1
log-slave-updates       = true

# enable GTID
gtid-mode = on
enforce-gtid-consistency = true
sync-master-info=1
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1

expire_logs_days        = 10
max_binlog_size         = 100M

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

2
задан 16 October 2016 в 06:15
1 ответ
SET GLOBAL SLAVE_NET_TIMEOUT = 60;
STOP SLAVE;
START SLAVE;

Вы правы, что скептически относитесь к тому, что это решит проблему, так как, похоже, не происходит таймаута... и поэтому вы хотите, чтобы он произошел, но это все равно должно быть решением. Я объясню.

Когда репликация, кажется, замирает без ошибок, IO = Да, SQL = Да, Seconds_Behind_Master = 0, это подразумевает висячее соединение репликации. Ведомый думает, что он подключен, и думает, что никаких новых событий не наступило.

В MySQL, встроенной асинхронной репликации, ведомый отвечает за инициирование соединения с мастером, и тогда его роль становится пассивной - по мере возникновения событий репликации, мастер автономно выталкивает события репликации на ведомого через это соединение, и ведомый, на седьмом уровне, ничего не делает в ответ. TCP, конечно, делает, но ни мастер, ни ведомый не знают об этом. До тех пор, пока не произойдет событие репликации, соединение просто простаивает, никакого взаимодействия не происходит. До тех пор, пока ни одна из сторон не увидит ничего подобного TCP FIN или RST, закрывающего соединение, Предполагается, что соединение повышается.

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

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

Тогда, при следующей отправке мастером события, после истечения этого таймаута, сеть, вероятно, ответит сбросом этого "неизвестного" соединения по направлению мастера, но не по направлению ведомого, потому что именно мастер инициировал пакет, который был частью "неизвестного" соединения. Поэтому ведомый думает, что у него есть соединение, когда на самом деле на другом конце трубы ничего нет.

Установка slave_net_timeout решает эту проблему очевидным и неочевидным образом. Неочевидное - это то, что нас особенно интересует, в то время как очевидное - это наше падение.

Когда ведомый соединяется с мастером, он просит мастера посылать сообщения о сердцебиении. Сердцебиение - это фиктивные события репликации, которые на самом деле не записываются в бинлог мастера или в релейный журнал ведомого. Они генерируются только тогда, когда в течение MASTER_HEARTBEAT_PERIOD секунд не произошло реального события репликации.

MASTER_HEARTBEAT_PERIOD, если явно не установлено значение CHANGE_MASTER_TO, то по умолчанию установлено значение slave_net_timeout / 2. Итак, неочевидный вклад настройки slave_net_timeout в решение проблемы заключается в том, что теперь ведущий будет активно посылать трафик, чтобы поддерживать соединение с другими устройствами, каждые 30 секунд (60/2), а в обратном случае, после 60 секунд вообще ничего, ведомый будет автоматически разрывать соединение и переподключаться к ведущему - фактически так же, как и при остановке и запуске ведомого - хотя этого никогда не должно происходить, если соединение не нарушено, потому что ведущий будет посылать эти сердечные ритмы по мере необходимости.

Если это решает вашу проблему, помните, что вам также нужно сделать изменение на slave_net_timeout постоянным, обновив my.cnf и перезапустив сервер -- в противном случае при следующем перезапуске сервера настройка вернется к прежним значениям и значением по умолчанию перед MySQL 5. 7 равно 3600.

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


Unrelated: обратите внимание, что MASTER_CONNECT_RETRY = 5 слишком низкое значение. Вы хотите, чтобы это значение было выше, или ведомый может слишком быстро отказаться от ведущего при отключении.

.
2
ответ дан 3 December 2019 в 11:31

Теги

Похожие вопросы