我有一个主服务器和几个从服务器复制一个数据库。我在 SLES 11 中的 MySQL 5.0 中使用。在容错测试期间,我发现当从属设备的网络连接断开(拔下电缆)然后恢复时,复制挂起。它没有显示任何错误,并且从站似乎正在运行,但Read_Master_Log_Pos
和Exec_Master_Log_Pos
值与主服务器上的日志位置不匹配。
这Slave_IO_State
是“等待主人发送事件”。
和Slave_IO_Running
值Slave_SQL_Running
都是“是”。
和Master_Log_File
匹配Relay_Master_Log_File
。
如果我停止并启动从属服务器或重新启动 mysql 守护程序,复制将再次开始工作。
关于我能做些什么的任何想法?
当 MySQL 从站连接到主站时,它会请求二进制日志流,并且主站会在发生时自动发送二进制日志事件,除非您使用半同步复制,否则不需要从站确认。
从站不发起任何流量,除了由 TCP 堆栈处理的低级确认。连接中断(在堆栈的各个层,不限于未插入的电缆)可能会导致连接以多种方式中断,包括由于超时或 ICMP 不可达消息或状态防火墙而导致主设备的 TCP 堆栈断开连接在机器“忘记” TCP 会话并默默地丢弃后续数据包之间,从服务器静静地坐着等待来自主服务器的下一个数据包。
这里的解决方案是全局变量
slave_net_timeout
。这是在从站上配置的。当 slave 连接到 master 时,在请求 binlog 流之前,它要求 master 发送心跳事件,这些事件的格式类似于 binlog 事件并流式传输,就好像它们是 master 的 binlog 中的下一个事件一样,但实际上并不增加二进制日志位置计数器。它们在正常操作中基本上是零开销,因为它们不会被发送,除非主服务器没有为从服务器的一半
slave_net_timeout
设置(默认值;或您可以在 期间配置的另一个值CHANGE MASTER TO
)生成新的 binlog 事件,因此心跳事件实际上只是当交通非常少时产生......所以据我所知,将这个值设置为低至几秒钟并没有任何真正的伤害。如果从站看到超时到期,它将关闭其连接并重新连接到主站。
在master没有意识到slave已经离开的远程机会上,当slave重新连接时,master会关闭原来的连接,因为一个MySQL master在接受一个新的slave连接时,会检查另一个slave是否有相同的连接
server_id
已连接,如果是,则断开原始连接。顺便说一句,这就是为什么配置相同server_id
(不受支持的配置)的两个从站无法成功保持连接到同一个主站的原因——一旦其中一个连接,就会导致另一个被碰撞,并且循环随之而来,每个从站强制断开另一个从站的连接。在 my.cnf 中将此变量设置为适当的低值并重新启动从站应该可以解决此问题。