您可以使用 CHANGE REPLICATION SOURCE TO 语句将副本切换到新的源。副本不会检查源上的数据库是否与副本上的数据库兼容;它只是从新源的二进制日志中的指定坐标开始读取和执行事件。在故障转移情况下,组中的所有服务器通常都是从同一个二进制日志文件执行相同的事件,因此更改事件的源不会影响数据库的结构或完整性,只要您在进行更改时小心。
副本应该启用二进制日志记录(--log-bin 选项),这是默认设置。如果您不使用 GTIDs 进行复制,那么副本也应该启用 --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 的原因是为了防止副本在将一个副本设置为新的源时接收更新两次。如果 Replica 1 启用了 --log-replica-updates,它将从 Source 接收的更新写入其二进制日志。这意味着,当 Replica 2 从 Source 切换到 Replica 1 作为其源时,它可能会从 Replica 1 接收已经从 Source 接收的更新。
确保所有副本都处理了其中继日志中的语句。在每个副本上,发出 STOP REPLICA IO_THREAD,然后检查 SHOW PROCESSLIST 的输出,直到您看到 Has read all relay log。当所有副本都满足这个条件时,它们可以被重新配置到新的设置上。在要升级为源的副本 Replica 1 上,发出 STOP REPLICA 和 RESET BINARY LOGS AND GTIDS。
在其他副本 副本 2 和 副本 3 上,使用 STOP REPLICA 和 CHANGE REPLICATION SOURCE TO SOURCE_HOST='副本 1'(其中 '副本 1' 代表 副本 1 的真实主机名)。要使用 CHANGE REPLICATION SOURCE TO,添加所有关于如何从 副本 2 或 副本 3 连接到 副本 1 的信息(用户、密码、端口)。在这种情况下,不需要指定 副本 1 的二进制日志文件名或读取位置,因为默认情况下是第一个二进制日志文件和位置 4。最后,在 副本 2 和 副本 3 上执行 START REPLICA。
一旦新的复制设置就绪,您需要告诉每个 Web 客户端 将其语句定向到 副本 1。从那时起,所有由 Web 客户端 发送到 副本 1 的更新都将被写入 副本 1 的二进制日志中,该日志现在包含自 源 不可用以来所有发送到 副本 1 的更新。
结果服务器结构如 图 19.5,“使用复制的冗余,源失败后” 所示。
当 源 再次可用时,您应该使其成为 副本 1 的副本。为此,在 源 上发出与之前在 副本 2 和 副本 3 上相同的 CHANGE REPLICATION SOURCE TO 语句。源 然后将成为 副本 1 的副本,并获取它在离线时错过的 Web 客户端 写入。
要使 源 再次成为源,请按照之前的过程进行,如同 副本 1 不可用且 源 将成为新的源。在此过程中,不要忘记在 源 上运行 RESET BINARY LOGS AND GTIDS,然后使 副本 1、副本 2 和 副本 3 成为 源 的副本。如果您忘记这样做,副本可能会从 Web 客户端 应用程序中获取过时的写入,dating from before the point at which 源 became unavailable。
您应该注意到,即使副本共享同一个源,也不存在副本之间的同步,因此在某些情况下,前面的过程可能不会按预期工作。然而,在实践中,所有副本的中继日志应该相对接近。
一种使应用程序了解源位置的方法是使用动态 DNS 条目来指向源主机。使用 BIND,您可以使用 nsupdate 动态更新 DNS。