如何使 AWS RDS MySQL 读取“副本”具有不同的模式?

如何使 AWS RDS MySQL 读取“副本”具有不同的模式?

而不是使用 AWS CLI/UI 来创造只读副本,我想创建一个具有“足够接近”架构的数据库实例,并且它是复制品。

我需要进行架构更改(排序规则更改),但无法在 MySQL 中实时完成。我想通过创建具有架构更改的读取“副本”来进行此更改,然后提升只读“副本”。

问题在于 AWS RDS MySQL 只读副本机制要求两个模式完全相同。

我知道这在 MySQL 中通常可以做到(虽然我不知道具体细节);我想在 AWS RDS 框架内完全做到这一点。

答案1

问题在于 AWS RDS MySQL 只读副本机制要求两个模式完全相同。

一般来说,复制需要这样做。

但是,如果您对“足够接近”的定义确实足够接近,那么您可以在 RDS for MySQL 中以与往常相同的方式完成此操作。

创建一个数据库实例...并将其设置为副本。

嗯,你不应该这么做。

在 RDS 之外,您也不会这样做。您总是必须从相同的副本开始,然后更改它,因为根据定义,复制依赖于已知的特定时间点,在该时间点上数据集和模式是相同的,在此之后,更改才有可能,只要 MySQL 确实认为它们“足够接近”。

“足够接近”的例子可能包括具有更多或更少索引的副本...但显然不包括诸如副本上的新唯一键或外键约束之类的东西,其中主数据违反了约束...并且排序规则更改可能会导致现有约束被违反,而没有任何实际数据更改。 (或者不是,如果您从不区分大小写切换到二进制)。

向从属服务器添加表是可以的,删除表则不行,甚至可以从表中添加列或删除列,当且仅当从第一列开始按序号位置排列的其余列相同时。也就是说,您可以向表的右边缘添加列或删除列;您不能更改列的顺序,但如果可以强制转换,您可以更改数据类型,比如增加 的长度VARCHAR。只要BINLOG_FORMAT主服务器上的 设置为,您就可以重命名列ROW,这通常是尝试此类更改时更好的选择。对于 RDS 来说,唯一的选择是MIXED。他们明智地阻止了严格STATEMENT基于 的复制。请注意,BINLOG_FORMAT从属服务器上的 和从属服务器转换无关。

MySQL 通常会尝试在复制期间隐式地进行类型转换。另请参阅主从表定义不同的复制了解 MySQL 对此的一般看法。

你可能确实能成功实现你的计划。如果没有,你应该很快就会发现。

但至少使用 RDS,如果您损坏了它,可以很容易地再试一次......并且,主服务器的完整性和性能不会受到损坏的副本的影响。

这是你的解决办法:

只读副本旨在支持读取查询,但您可能需要偶尔进行更新,例如添加索引以加快访问副本的特定类型的查询。您可以通过read_only在只读副本的数据库参数组中将参数设置为 0 来启用更新。

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html#USER_ReadRepl.MySQL

除非这是您唯一的副本,否则请务必将参数组复制到新副本,将该参数组应用于副本,然后更改新组的设置。将其他副本保留为可写状态会产生副作用,从而导致出现问题。

一旦完成并生效,副本即可写入。如果您提议的更改确实“足够接近”,那么在您直接登录副本并使用与主服务器相同的凭据进行更改后,副本将继续复制。

或者,如果不是,复制将会中断。

对副本进行架构更改时无需暂停复制,因为当副本上正在进行涉及下一个复制事件需要访问的对象的 DDL 操作时,MySQL 会使用正常锁定机制(如表元数据锁)自动暂停复制事件的执行。

在 RDS 中,该SHOW SLAVE STATUS语句的工作方式与标准 MySQL 相同。如果Slave_IO_RunningSlave_SQL_Running都显示Yes并且Seconds_Behind_Master不显示NULL,则副本未损坏;如果Seconds_Behind_Master= 0,则副本与主服务器实时同步(> 0 表示它滞后,正在尝试赶上)。


问题:一个很长的更改(重新整理列将需要一个小时左右)会给主服务器造成问题吗?我正在考虑大量备份复制日志,以及在只读副本中的锁上阻塞的流量。

这对于 RDS 来说不是问题,原因有二。

最重要的原因是 MySQL 复制使用两个线程 - 一个用于从主服务器接收日志(I/O 线程),另一个用于执行日志(SQL 线程) - 这些线程就是我上面提到的“正在运行”状态的线程。当副本服务器由于本地更改而阻止事件执行时,它会继续接收这些事件。只要副本服务器的存储空间不耗尽,释放锁后一切都会按预期继续。

此外,虽然在这种情况下意义不大,但由于 I/O 线程将保持运行,RDS 不使用标准expire_logs_days系统变量来清除主服务器上的旧 binlog。相反,它会自行清除它们——只要您的副本不再需要它们,但在此之前不会清除——这很有用,因为它们会计入您的存储分配。(您也可以如果需要,配置 RDS 让它们保留更长时间)。我已经完全停止了 RDS 复制超过 24 小时,然后又重新启动了它,没有任何问题。

相关内容