与在主实例意外故障时支持自动故障转移的 InnoDB 集群不同,InnoDB 副本集没有自动故障检测或类似于组复制提供的基于共识的协议。如果主实例不可用,则需要手动故障转移。丢失主实例的 InnoDB 副本集实际上是只读的,要进行任何写入更改,必须选择一个新的主实例。如果您无法连接到主实例,并且无法使用
安全地执行切换到新主实例的操作,如第 9.7 节“更改主实例” 中所述,请使用 ReplicaSet
.setPrimaryInstance()
操作执行强制故障转移。这是最后的手段,仅在当前主实例不可用且无法以任何方式恢复的灾难情况下使用。ReplicaSet
.forcePrimaryInstance()
强制故障转移是一种具有潜在破坏性的操作,必须谨慎使用。
如果目标实例不可达(或为空),则自动选择最新的实例并将其提升为新的主实例。如果目标实例可达,则将其提升为新的主实例。其他可达的辅助实例从此新的主实例复制数据。目标实例必须具有可达实例中最新的 GTID_EXECUTED
集,否则操作将失败。
故障转移与计划的主实例更改不同,因为它在不与旧主实例同步或更新的情况下提升辅助实例。这会产生以下主要后果:
在旧主实例发生故障时,尚未应用于辅助实例的任何事务都将丢失。
如果旧主实例仍在运行并处理事务,则会出现脑裂,并且旧主实例和新主实例的数据集会发生分歧。
如果最后一个已知的主实例仍然可达,则
操作将失败,以降低脑裂情况的风险。但管理员有责任确保其他实例无法访问旧主实例,以防止或最大程度地减少此类情况的发生。ReplicaSet
.forcePrimaryInstance()
强制故障转移后,旧主实例被新主实例视为无效,并且不能再成为副本集的一部分。如果以后发现可以恢复的实例,则必须将其从副本集中删除,并将其作为新实例添加。如果辅助实例在故障转移期间无法切换到新的主实例,则该辅助实例被视为无效。
故障转移后可能会出现数据丢失,因为旧主实例可能具有尚未复制到要提升的辅助实例的事务。此外,如果假定已发生故障的实例仍然可以处理事务,例如,因为它所在的网络仍在运行但 MySQL Shell 无法访问,则它会继续与已提升的实例发生分歧。在实例上的事务集发生分歧后进行恢复需要手动干预,并且在某些情况下可能无法实现,即使已发生故障的实例可以恢复也是如此。通常,从需要强制故障转移的灾难中恢复的最快捷、最简单的方法是丢弃此类分歧的事务,并从新提升的主实例重新配置新实例。