将 GitHub.com升级到MySQL 8.0


GitHub 使用 MySQL 来存储大量关系数据。这是我们如何将生产组无缝升级到 MySQL 8.0 的故事。

15 多年前,GitHub 最初是一个带有单个 MySQL 数据库的 Ruby on Rails 应用程序。从那时起,GitHub 不断发展其 MySQL 架构,以满足平台的扩展和弹性需求,包括构建高可用性、实现测试自动化,以及数据分区。如今,MySQL 仍然是 GitHub 基础设施和我们选择的关系数据库的核心部分。

这是我们如何将 1200 多台 MySQL 主机升级到 8.0 的故事。在不影响我们的服务级别目标 (SLO) 的情况下升级机群绝非易事 - 规划、测试和升级本身花费了一年多的时间,并且需要 GitHub 内多个团队的协作。

升级的动机
为什么升级到 MySQL 8.0?随着 MySQL 5.7 的生命周期即将结束,我们将我们的设备升级到了下一个主要版本 MySQL 8.0。我们还希望使用能够获得最新安全补丁、错误修复和性能增强的 MySQL 版本。我们还想测试 8.0 中的一些新功能并从中受益,包括即时 DDL、不可见索引和压缩 bin 日志等。

GitHub 的 MySQL 基础设施
在我们深入了解如何进行升级之前,让我们先从 10,000 英尺的高度看一下我们的 MySQL 基础设施:

  • 由 1200 多台主机组成。它是我们数据中心中的 Azure 虚拟机和裸机主机的组合。
  • 我们存储超过 300 TB 的数据,并在 50 多个数据库集群中每秒处理 550 万次查询。
  • 每个集群都配置为具有主加副本集群设置的高可用性。
  • 我们的数据已分区。我们利用水平和垂直分片来扩展 MySQL 集群。我们有 MySQL 集群来存储特定产品领域的数据。我们还为单主 MySQL 集群无法满足的大域区域提供了水平分片的 Vitess 集群。
  • 我们拥有一个庞大的工具生态系统,包括 Percona Toolkit、gh-ost、orchestrator< /span> 以及用于操作车队的内部自动化。

所有这些总结起来就是一个多样化且复杂的部署,需要在维护我们的 SLO 的同时进行升级。

准备旅程
作为 GitHub 的主要数据存储,我们对可用性保持高标准。由于我们的机群规模和 MySQL 基础设施的重要性,我们对升级过程提出了一些要求:

  • 我们必须能够升级每个 MySQL 数据库,同时遵守我们的服务级别目标 (SLO) 和服务级别协议 (SLA)。
  • 我们无法解释测试和验证阶段的所有故障模式。因此,为了保持在 SLO 范围内,我们需要能够回滚到 MySQL 5.7 的先前版本而不中断服务。
  • 我们的 MySQL 队列中的工作负载非常多样化。为了降低风险,我们需要自动升级每个数据库集群并安排其他重大更改。这意味着升级过程将是一个漫长的过程。因此,我们从一开始就知道我们需要能够维持运行混合版本环境。

升级准备工作于 2022 年 7 月开始,即使在升级单个生产数据库之前,我们也需要实现几个里程碑。

确保应用程序兼容性
我们将 MySQL 8.0 添加到了所有使用 MySQL 的应用程序的持续集成 (CI) 中。我们在 CI 中并行运行 MySQL 5.7 和 8.0,以确保在长时间的升级过程中不会出现回归。我们检测到 CI 中的各种错误和不兼容性,帮助我们删除任何不受支持的配置或功能,并转义任何新的保留关键字。
为了帮助应用程序开发人员过渡到 MySQL 8.0,我们还启用了一个选项,可以在 GitHub Codespaces 中选择 MySQL 8.0 预构建容器进行调试,并提供 MySQL 8.0 开发集群以进行额外的预生产测试。

升级计划

  • 第 1 步:滚动复制副本升级
  • 步骤 2:更新复制拓扑
  • 步骤 3:将 MySQL 8.0 主机提升为primary机
  • 步骤 4:升级面向内部的实例类型
  • 第 5 步:清理