Mysql GTID 复制停止工作

Mysql GTID 复制停止工作

我已经在主服务器和从服务器之间设置了 mysql gtid 复制。有趣的是,我发现复制在几分钟后停止工作,我必须使用stop slavestart 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,但问题仍然困扰着我。任何帮助都将不胜感激。

答案1

SET GLOBAL SLAVE_NET_TIMEOUT = 60;
STOP SLAVE;
START SLAVE;

你怀疑这是否能解决问题,这是对的,因为似乎没有发生超时……你也没有一个可能发生,但这仍然是解决方案。我会解释的。

当复制似乎停滞且没有错误时,IO = Yes、SQL = Yes、Seconds_Behind_Master = 0,这意味着复制连接挂起。从属服务器认为它已连接,并且认为没有新事件到达。

在 MySQL 本机异步复制中,从服务器负责启动与主服务器的连接,然后其角色变为被动 - 当复制事件发生时,主服务器通过该连接自主地将复制事件推送到从服务器,而从服务器在第 7 层不做任何响应。TCP 当然会这样做,但主服务器和从服务器都不知道这一点。在发生复制事件之前,连接只是处于空闲状态,没有发生任何交互。只要双方都没有看到任何类似 TCPFINRST关闭连接的东西,就认为连接已启动。

如果主服务器和从服务器通过任何以状态方式处理 TCP 连接的设备(防火墙、NAT 设备、EC2 安全组)连接,则这种情况会在流量较低时发生故障,因为状态性通常意味着超时计时器。如果连接空闲时间过长,“网络”(我将使用这个术语来表示将某事物连接到其他事物的事物)将从其状态表中清除该连接——该连接被“遗忘”。15 分钟是一个常见的值。

当发生这种超时时,网络通常不会采取任何措施,只是简单地从其内部内存结构中删除该连接。通常不会发生任何事。连接各方被认为已放弃该连接,或者流量已转移到另一个网络,因此清除其内存中的连接的设备(正确地)不会主动尝试通知其他节点该连接不再可行。

然后,下次主设备发送事件时,在此超时时间过后,网络可能会通过在主设备方向上重置此“未知”连接来做出响应,但不会在从设备方向上重置此连接,因为主设备是发起“未知”连接数据包的一方。因此从设备认为它有一个连接,而实际上管道的另一端什么也没有。

环境slave_net_timeout用一种明显和不明显的方式解决了这个问题。不明显的方式是我们特别感兴趣的,而明显的方式则是我们的后备。

当从服务器连接到主服务器时,它会要求主服务器发送心跳消息。心跳是虚拟复制事件,实际上不会写入主服务器的 binlog 或从服务器的中继日志。只有当没有发生真正的复制事件时才会生成它们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值太低了。您需要将其值提高很多,否则在发生故障时,从服务器可能会过快放弃主服务器。

相关内容