Я установил репликацию mysql gtid между ведущим и ведомым. интересно то, что я обнаружил, что репликация перестала работать через несколько минут, и мне пришлось использовать stop slave
и start 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
Я не видел никаких проблем в show slave status
, но проблема все еще меня прерывает. Заранее благодарим за любую помощь.
SET GLOBAL SLAVE_NET_TIMEOUT = 60;
STOP SLAVE;
START SLAVE;
Вы правы, сомневаясь в том, что это решит проблему, поскольку тайм-аут, похоже, не наступает ... хотеть может произойти, но это должно быть решением. Я объясню.
Когда кажется, что репликация останавливается без ошибок, IO = Yes, SQL = Yes, Seconds_Behind_Master = 0, это означает, что соединение репликации зависло. Раб думает, что это связано, и думает, что не произошло никаких новых событий.
В собственной асинхронной репликации MySQL ведомое устройство отвечает за инициирование соединения с ведущим устройством, а затем его роль становится пассивной - когда происходят события репликации, ведущее устройство автономно передает события репликации ведомому устройству через это соединение, а ведомое устройство на уровне 7 ничего не делает в ответ. 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
на меньшее значение, но это решает только половину проблемы. Когда соединение действительно терпит неудачу, ведомому серверу требуется слишком много времени, чтобы это заметить.
Несвязанный: обратите внимание, что MASTER_CONNECT_RETRY = 5
слишком низко. Вы хотите, чтобы это значение было намного выше, иначе ведомое устройство может слишком быстро отказаться от ведущего в случае сбоя.