使用只读副本提升在 AWS RDS MySQL 数据库上创建索引

Using Read Replica Promotion to Create Index On AWS RDS MySQL Database

我想在 Amazon RDS 上的数据库中为 MySQL table 添加索引,但我不想在创建索引时停止使用数据库。 answer 建议使用只读副本提升,首先在只读副本上创建索引,然后提升只读副本。我创建了一个只读副本来尝试这种方法,但是当我尝试更改只读副本上的索引时,我得到 ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement。我该怎么做才能编辑只读副本,这会阻止 Amazon 继续更新只读副本以匹配主数据库吗?

默认情况下只读副本是只读的,直到您将它们自定义为读写。

您可以将 Amazon RDS 数据库实例只读副本配置为 read/write,方法是将您为数据库实例创建的数据库参数组的 read_only 参数设置为 false。按照此开发人员指南为您的只读副本实现 read/write。然后你就可以实现你的用例了。

https://aws.amazon.com/premiumsupport/knowledge-center/rds-read-replica/

您尝试的模式是:

  1. 当应用写入 current_db 时,next_db 会执行构建新索引的破坏性工作。一旦 next_db 追上 ...
  2. [棘手] 安全地将应用流量从 current_db 切换到 next_db
  3. 老主下线(或者重建,或者加索引,什么的,现在都是多余的)

使用 MySQL,您必须非常小心第 2 步,尤其是当您的应用程序 运行ning 在 2+ 个实例上时。如果您的应用层的一部分写入 current_db 而您的应用层的一部分写入 next_db,如果您不小心,可能会发生坏事。这里有两种保持安全的方法:

  • 三秒切换:停止对 current_db 的所有写入,然后验证 next_db 是否已完全复制,然后开始写入 next_db。如果 next_db 已准备就绪,此切换间隔会导致 "downtime" 1-3 秒,具体取决于您键入的速度。
  • 零停机时间:使用两个数据库实例创作写入,您需要注意数据库设计。 MySQL 最重要的问题是在两个数据库实例上使用奇数和偶数来自动递增行 ID。否则,两个数据库实例都会创建具有相同 ID 的新数据库行!糟糕!数据损坏!

不幸的是,RDS 只读副本提升似乎不足以实现零停机模式。 以下是 RDS 文档关于读取副本提升的内容:

The promotion process takes a few minutes to complete. When you promote a Read Replica, replication is stopped and the Read Replica is rebooted. When the reboot is complete, the Read Replica is available as a single-AZ DB instance.

这并不能真正实现零停机时间。但是,您可以使用该机制安全地进行 "Three [Minute] Cutover" 更新。遗憾的是,由于重新启动,这将需要几分钟时间。方法如下:

  1. 添加一个只读副本并让它赶上主服务器
  2. 将只读副本标记为可写 (link) 并应用向前兼容的架构更新[不要发送数据库行更新!]
  3. 停止应用程序(写入)到旧主服务器的流量(b/c 复制即将结束)。如果您的应用程序支持它,它可能 运行 这次处于只读模式,或者假脱机写入队列。
  4. 升级只读副本(link)...大约需要 3 分钟。
  5. 将您的应用指向您升级的新数据库实例。
  6. 验证您的应用是否运行正常(可能需要一个小时;要多疑)。
  7. 销毁旧数据库实例。

如果您真的想要 "Zero Downtime" 更新,则需要调查: http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html

最后一句话:无论您选择做什么,我都建议您在实际系统上尝试之前先使用您的应用程序的模拟版本练习一次! :-)