您可以使用 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。