您可以使用 CHANGE REPLICATION SOURCE TO 语句告诉副本切换到新的源。副本不会检查源上的数据库是否与副本上的数据库兼容;它只是开始从新源的二进制日志中的指定坐标读取和执行事件。在故障转移情况下,组中的所有服务器通常都在从同一个二进制日志文件中执行相同的事件,因此更改事件源不应影响数据库的结构或完整性,前提是您在进行更改时谨慎操作。
副本应启用二进制日志记录运行(--log-bin 选项),这是默认设置。如果您没有使用 GTID 进行复制,那么副本还应使用 --log-replica-updates=OFF 运行(记录副本更新是默认设置)。这样,副本就可以随时准备成为源,而无需重新启动副本 mysqld。假设您具有 图 19.4,“使用复制实现冗余,初始结构” 中所示的结构。
在此图中,Source 保存源数据库,Replica* 主机是副本,Web Client 机器正在发出数据库读写操作。仅发出读取操作的 Web 客户端(通常连接到副本)没有显示,因为它们不需要在发生故障时切换到新服务器。有关读写扩展复制结构的更详细示例,请参阅 第 19.4.5 节,“使用复制进行扩展”。
每个 MySQL 副本(Replica 1、Replica 2 和 Replica 3)都是启用了二进制日志记录运行的副本,并且使用 --log-replica-updates=OFF。由于指定了 --log-replica-updates=OFF 后,副本从源接收到的更新不会写入二进制日志,因此每个副本上的二进制日志最初都是空的。如果由于某种原因 Source 变得不可用,您可以选择其中一个副本作为新的源。例如,如果您选择 Replica 1,则所有 Web Clients 应重定向到 Replica 1,它将更新写入其二进制日志。然后,Replica 2 和 Replica 3 应从 Replica 1 进行复制。
使用 --log-replica-updates=OFF 运行副本的原因是,为了防止在您使其中一个副本成为新的源的情况下,副本两次接收更新。如果 副本 1 启用了 --log-replica-updates(默认情况下),它会将其从 源 收到的任何更新写入自己的二进制日志。这意味着,当 副本 2 从 源 更改为 副本 1 作为其源时,它可能会从 副本 1 接收已从 源 接收到的更新。
确保所有副本都已处理其中继日志中的任何语句。在每个副本上,发出 STOP REPLICA IO_THREAD,然后检查 SHOW PROCESSLIST 的输出,直到您看到 Has read all relay log。当所有副本都为真时,它们可以重新配置为新的设置。在被提升为源的副本 副本 1 上,发出 STOP REPLICA 和 RESET BINARY LOGS AND GTIDS。
在其他副本 副本 2 和 副本 3 上,使用 STOP REPLICA 和 CHANGE REPLICATION SOURCE TO SOURCE_HOST='Replica1'(其中 'Replica1' 表示 副本 1 的真实主机名)。要使用 CHANGE REPLICATION SOURCE TO,添加有关如何从 副本 2 或 副本 3 连接到 副本 1 的所有信息(user、password、port)。在这种情况下发出该语句时,无需指定要从中读取的 副本 1 二进制日志文件或日志位置的名称,因为第一个二进制日志文件和位置 4 是默认值。最后,在 副本 2 和 副本 3 上执行 START REPLICA。
一旦新的复制设置到位,您需要告诉每个 Web 客户端 将其语句定向到 副本 1。从那时起,所有由 Web 客户端 发送到 副本 1 的更新都将写入 副本 1 的二进制日志,该日志将包含自 源 变得不可用以来发送到 副本 1 的所有更新。
生成的服务器结构显示在 图 19.5,“使用复制的冗余,源故障后” 中。
当 源 再次变得可用时,您应该将其作为 副本 1 的副本。为此,在 源 上发出与之前在 副本 2 和 副本 3 上发出的相同的 CHANGE REPLICATION SOURCE TO 语句。然后,源 成为 副本 1 的副本,并接收它在脱机期间错过的 Web 客户端 写入。
要再次使 源 成为源,请使用前面的过程,就好像 副本 1 不可用且 源 将成为新的源一样。在此过程中,不要忘记在将 副本 1、副本 2 和 副本 3 设为 源 的副本之前,在 源 上运行 RESET BINARY LOGS AND GTIDS。如果您未能这样做,副本可能会接收来自 Web 客户端 应用程序的过时写入,这些写入可以追溯到 源 变得不可用的时间点之前。
您应该意识到,即使副本共享同一个源,它们之间也没有同步,因此一些副本可能远远领先于其他副本。这意味着在某些情况下,前面示例中概述的过程可能无法按预期工作。然而,在实践中,所有副本上的中继日志应该相对接近。
保持应用程序了解源位置的一种方法是为源主机设置一个动态 DNS 条目。使用 BIND,您可以使用 nsupdate 动态更新 DNS。