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

使用读取副本提升在AWS RDS MySQL数据库上创建索引,mysql,amazon-web-services,indexing,server,amazon-rds,Mysql,Amazon Web Services,Indexing,Server,Amazon Rds,我想在AmazonRDS上的数据库中向MySQL表添加索引,但我不想在创建索引时停止使用数据库。这建议使用读取副本升级,首先在读取副本上创建索引,然后升级读取副本。我创建了一个读取副本来尝试这种方法,但是当我尝试更改读取副本上的索引时,我得到错误1290(HY000):MySQL服务器正在使用--read-only选项运行,因此它无法执行此语句。如何使其能够编辑读取副本,这是否会阻止Amazon继续更新读取副本以匹配主数据库?读取副本默认为只读,直到您将其自定义为读写 通过将为数据库实例创建的数

我想在AmazonRDS上的数据库中向MySQL表添加索引,但我不想在创建索引时停止使用数据库。这建议使用读取副本升级,首先在读取副本上创建索引,然后升级读取副本。我创建了一个读取副本来尝试这种方法,但是当我尝试更改读取副本上的索引时,我得到
错误1290(HY000):MySQL服务器正在使用--read-only选项运行,因此它无法执行此语句。如何使其能够编辑读取副本,这是否会阻止Amazon继续更新读取副本以匹配主数据库?

读取副本默认为只读,直到您将其自定义为读写

通过将为数据库实例创建的数据库参数组的只读参数设置为false,可以将Amazon RDS数据库实例读取副本配置为读/写。按照本开发人员指南实现读/写复制副本。然后您将能够实现您的用例


您尝试的模式是:

  • 当应用程序写入当前的_-db时,next_-db将执行构建新索引的破坏性工作。一旦下一个数据库赶上
  • [技巧]安全地将应用程序流量从当前\u db切换到下一个\u db
  • 让旧主机离线(或者重建它,或者添加索引,或者其他什么,现在都是多余的)
  • 对于MySQL,您必须非常小心第2步,尤其是当您的应用程序运行在2+个实例上时。如果应用层的一部分写入当前的_db,而应用层的一部分写入下一个_db,如果不小心,可能会发生不好的事情。这里有两种保持安全的方法:

    • 三秒切换:停止对当前_db的所有写入,然后验证下一个_db是否已完全复制,然后开始对下一个_db的写入。如果next_db热且准备就绪,则此切换间隔将导致1-3秒的“停机”,具体取决于您键入的速度
    • 零停机时间:使用两个db实例编写写操作时,需要注意db设计。MySQL最重要的问题是对两个db实例上的自动递增行ID使用奇偶编号。否则,两个DB实例将创建具有相同ID的新DB行!坏!数据损坏
    不幸的是,RDS读取副本升级似乎不足以实现零停机模式。 以下是RDS文档关于读取副本提升的说明:

    促销过程需要几分钟才能完成。当你 升级读取副本时,复制停止,读取副本停止 重新启动。重新启动完成后,读取副本可用 作为单个AZDB实例

    这并不能真正实现零停机。然而,您可以使用该机制安全地进行“三分钟”切换更新。遗憾的是,由于重新启动,这将需要几分钟的时间。以下是方法:

  • 添加一个读取副本,让它赶上主副本
  • 将读取副本标记为可写()并应用转发兼容的架构更新[不要发送DB行更新!]
  • 停止对旧主机的应用(写入)通信(b/c复制即将结束)。如果你的应用程序支持它,那么这次它可以以只读模式运行,或者spool写入队列
  • 升级读取副本()。。。大约需要3分钟
  • 将应用程序指向您已升级的新DB实例
  • 验证你的应用程序是否正常运行(可能需要一个小时;多疑)
  • 销毁旧数据库实例
  • 如果您确实想要“零停机”更新,您需要调查:


    最后一句话:无论你选择做什么,我建议在你的实时系统上试用之前,先用你的应用程序的模拟版本练习一下

    您的主RDS上是否存在该索引?不,它不在主RDS上。不确定您正在运行的版本,但所有这些问题可能完全没有必要。。。MySQL 5.6允许在不锁定表的情况下添加索引。@Michael sqlbot是5.6中的默认行为吗?你能给我指一下文件吗。我发现的一切都表明,当数据库运行时,它将无法工作,但在新版本中,这可能不再是一个问题。即使是在副本上,创建全文索引也需要11个小时,但如果不必经历升级副本和在副本上重新打印所有内容的麻烦,那就太好了。看起来不像默认值,但可以这样做:
    ALTER TABLE my_TABLE ADD INDEX my_TABLE\u idx(my_列),ALGORITHM=INPLACE,LOCK=NONE