在我工作的公司中,我们使用简单的主次复制设置。如果主系统因任何原因发生故障,我们手动进行切换。这也意味着,MySQL 几乎不会更新。我想让它成为可能,在不停机的情况下更新服务器。由于各种原因,我们不想要一个(过度)复杂的解决方案。所以我想知道,为了实现我的目标,是否可以像这样简单:
启用 GTID 的主-主复制和半同步复制。Pacemaker 将虚拟 IP 从一台服务器切换到另一台服务器,因此我可以停止一台服务器进行更新。然后切换回来并更新另一台服务器。
对于 Primary-Primary 复制,我没有以不同方式配置 auto-increment-increment。所有写入进程都将使用起搏器的虚拟 IP,因此只会写入一台主机。
我们在我的公司这样做。我们运行了数千个使用这种方法的 MySQL 主-主对。我们开发了一项服务来执行您描述的切换。我们称其为“成功转移”,因为它比故障转移具有更积极的含义。我们可以并且确实在一天中的任何时间运行它,甚至不需要通知应用程序团队我们正在这样做。
以下是一般步骤:
认为:
“Master1”是当前可写的主 MySQL 实例,其中定义了 VIP。
“Master2”是一个副本,处于只读模式。
如果它是自动化的,只要没有明显的复制延迟,这将导致不到一秒的停机时间。移动 VIP 比更新 DNS 快得多。
然后应用程序必须重新连接到 VIP,从而访问新的主实例并重新运行它们需要的任何查询。
显然,应用程序不应该使用备用 MySQL 实例,因为重点是允许它离线以进行更新、配置更改等。如果 MySQL 正在运行的主机服务器出现问题,这也为您提供了一种快速响应的方法上。我们每周都会遇到一些主机崩溃或磁盘故障,因此我们快速执行此切换以确保应用程序可以继续运行。
不可避免的是,这会导致应用程序连接断开并必须重新连接的短暂“短暂”,但它比任何其他解决方案都更短暂的中断。尽管如此,应用程序必须设计为检测断开的连接并重新连接。我们最大的问题是教育应用程序开发人员这样做。他们一直抱怨说他们会因为失去连接而收到警报,我们告诉他们,“我们已经记录了您需要做的事情——它不应该因为一个信号而发出警报。”
这个系统已经工作了好几年,但我们现在有一个混合环境,我们有许多云 MySQL 实例。我们需要一个新的解决方案,因为我们无法在云中使用 BGP 创建 VIP。
因此,我们使用Envoy作为 MySQL 的代理进行了原型设计。我们相信这是可行的,但是我们需要开发一个服务来在我们进行成功转移时通知 Envoy 代理更改。Envoy 支持 GRPC 协议,因此我们可以动态地向它发送消息,它会开始将流量路由到不同的目标 MySQL 实例。这种基于代理的解决方案在云中的工作方式应该与在数据中心中的工作方式相同。但是这个解决方案可能比你想象的要多。
我们也可以使用ProxySQL来做类似的事情,但是 Envoy 在我们公司已经大量采用了服务到服务的流量,所以如果我们可以利用它而不是一种新型代理,我们就可以使用更少的技术来实现利用。
更新评论:
上面列表中的第 4 步等待复制赶上,而两个实例都是只读的。因此,在此期间 Master1 上不允许有新的更新,而 Master2 只需执行在 Master1 设置为只读之前提交的一组剩余更新。希望这是一个非常短暂的等待,除非 Master2 已经落后很多。
运行 successover 的服务如果检测到 Master2 具有高复制延迟,则甚至拒绝开始操作。鼓励用户稍后再试。
当然,在现实世界中,有时您必须因为紧急情况而超越这种限制,因此可以选择强制继承。但这会带来风险,因为如果您将 Master2 设为主要并开始允许直接在其上进行新查询,而由于复制滞后仍有待处理的未完成更新,您最终会陷入脑裂的情况:您可以进行update 然后将被二进制日志中过去实际发生的事件替换。
所以理论上你可以在 Master2 上启用 VIP,但让 Master2 保持只读状态,直到它完全赶上复制。这至少执行了部分成功转移,并允许客户端临时读取数据,但不能更新。这对于某些应用程序来说可能在短时间内是可以接受的,但这取决于应用程序的要求。
在实践中,我们的successover 实现不会执行这种临时只读模式。我们只是尽量不愿意使用强制继承选项,因为脑裂极难清理(可能不可能)。我们宁愿在没有复制延迟的情况下尝试successover。