亚马逊AWS官方博客

在Amazon RDS for MySQL数据库上提升MySQL只读副本的最佳实践

原文链接:

https://aws.amazon.com/cn/blogs/database/best-practices-for-using-a-mysql-read-replica-to-upgrade-an-amazon-rds-for-mysql-database/

 

在Amazon RDS for MySQL数据库上提升MySQL只读副本的最佳实践

在日常运营中,我们常常通过以下方法对MySQL数据库执行维护:

  1. 为数据库创建读取(只读)副本。
  2. 对读取副本执行维护。
  3. 升级读取副本以替换源数据库。

在本文中,我们将了解如何通过上述方法在Amazon RDS for MySQL数据库上执行主版本升级,以及与之相关的最佳实践。此外,我们还将探讨可供选择的其他操作步骤。

在由5.7版本升级至8.0版本之前,我们首先需要排除各类极端情况。关于这些极端情况的更多详细信息,请参阅由MySQL 5.7升级至8.0前的预检查事项

本文将着重介绍关于升级规划以及过渡至新数据库实例的最佳实践。

解决方案概述

通过本文介绍的方法,您可以在非关键数据库实例上测试升级效果,避免生产数据库实例因升级而产生任何可能的停机。您可以在维护阶段全面执行测试,并验证升级是否成功。这里需要强调,提前设置全新环境非常重要。相关最佳实践的基本思路,在于尽可能缩短升级期间所出现的中断容器期,借此减少停机时间。

在本用例中,我们假定当前生产环境具有以下特点:

  • 多可用区部署
  • 启用备份机制
  • 具有一个或多个读取副本以进行伸缩

下图所示,为这套架构的基本情况。

除非另有说明,否则以下各项操作步骤不需要严格按顺序操作。其基本目标在于先设置新的数据库实例,而后进行实例转换。我们姑且按照以下顺序进行论述:

  1. 创建一个新的读取副本。
  2. 将目标数据库实例转换为多可用区部署并启用备份。
  3. 升级目标实例。
  4. (可选)创建其他读取副本。
  5. (可选)创建自定义参数组。
  6. (可选)通过启用多线程复制,解决地址副本滞后的问题。
  7. 执行切换。

创建一个新的读取副本

这套新的读取副本,最终将成为新的生产数据库实例。如下图所示,我们将此新数据库实例称为目标数据库实例(target DB instance)。

将目标数据库实例转换为多可用区部署并启用备份机制

默认情况下,我们以单可用区部署的形式创建一个新读取副本,并为其启用备份机制。由于目标数据库实例最终将成为生产数据库实例,因此最佳实践建议配置多可用区部署并立即启用备份机制。

您必须重新启动读取副本,才能启用二进制日志记录,这样我们才能在不产生任何影响的前提下完成实例中断。

同样,要转换为多可用区部署,我们需要为目标数据库实例创建备份,而后将该备份还原至其他可用区内运行的辅助数据库实例处。在转换为多可用区部署时,在新辅助副本与目标数据库实例的主副本进行同步期间(时间较短),可能会对目标数据库实例的写入延迟产生影响。同样,请提前执行此步骤,以避免后续对性能产生影响。

下图所示,为此架构的基本情况中。

 

升级目标实例

在极少数情况下,升级至MySQL 8.0版本可能引发不兼容问题,请在读取副本上测试升级过程以保护源生产数据库实例不受影响。在完全确定升级成功且不存在意外问题之后,方可解除这种随时回滚的保护性状态。您可以根据需求进行多轮升级测试。

此外,您也可以将源生产数据库实例的快照还原至临时数据库实例处,借此测试临时数据库实例上的升级过程是否顺利。这种独立验证更加简便易行,本文强烈建议大家采取这一方法。

下图所示,为此架构的基本情况。

创建其他读取副本

作为可选步骤,如果您希望读取副本支持读取弹性伸缩(或者出于其他考量),也可以借此机会根据最终配置需求创建其他读取副本。

下图所示,为此架构的基本情况。

创建自定义参数组

作为可选项,您也可以借此机会创建自定义参数组,以将各项参数应用于目标数据库实例以及所有读取副本。

通过启用多线程复制,解决副本滞后问题

在默认情况下,MySQL二进制日志复制将以单线程形式在读取副本上执行。而一旦源数据库实例上出现高并发性工作负载,则可能导致读取副本上的复制操作发生滞后。

因此在规划切换至目标数据库实例期间的中断问题时,必须停止应用程序工作负载(停机),等待副本滞后度降至零,而后再执行切换。为了尽可能减少影响,请考虑在各读取副本以及目标数据库实例上进行多线程复制。MySQL 5.7版本中添加了多线程复制功能,可以大大减少复制操作的滞后问题。

我们使用以下三项参数启用多线程复制。这些设置适用于大多数配置方案:

  • slave_parallel_workers=8
  • slave_parallel_type=LOGICAL_CLOCK
  • slave_preserve_commit_order=1

为了详加说明,这里我们假定存在两套指向同一源数据库的副本。下图中的橙色线代表使用默认参数,蓝色线使用以上参数设置。在这种情况下,测试工作负载的副本滞后为零。请注意,不同工作负载有着不同的情况,因此您需要持续关注副本的滞后问题。

现在您的目标环境已经准备就绪,接下来即可停机并升级目标数据库实例,而后利用它替换源生产数据库实例。

一般来说,到这里的所有操作都可以提前几天完成,由此保证新环境能够持续运行一段时间,进一步将维护周期缩短到最低程度。

执行切换

现在,目标环境已经准备就绪,接下来即可规划维护窗口以切换至新的目标实例。

  • 停止来自应用程序的流量,中断期正式开始。
  • 使用AWS命令行界面(AWS CLI)或者AWS管理控制台,对目标读取副本执行升级。

此步骤会断开读取副本与源生产数据库实例之间的连接,并令目标数据库实例成为独立实例(详见下图)。

  • 作为可选步骤,如果要为数据库维护相同的DNS端点,则可以在源生产数据库实例与目标数据库实例之间交换数据库端点:
    1. 调用 modify-db-instance CLI命令,对源生产数据库实例进行重命名。
    2. 再次调用 modify-db-instance CLI命令,根据源数据库标识符对目标数据库实例进行重命名。
  • 重命名完成之后,您可以结束中断并重新启动应用程序。此次应用程序将通过解析指向新的生产实例。

总结

看似步骤繁杂,但本文的建议已经涵盖了您需要执行的几乎所有必要维护步骤,足以轻松完成数据库实例升级。与此同时,您还可以将维护期间的中断时长控制在最低限度。

 

本篇作者

Phil Intihar

Amazon Web Services公司首席数据库工程师