如何使 AWS RDS MySQL Read“副本”具有不同的架构?

Mar*_*tos 1 mysql-replication amazon-web-services amazon-rds

我不想使用 AWS CLI/UI创建只读副本,而是想创建一个具有“足够接近”架构的数据库实例并将其设置为副本。

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

问题在于 AWS RDS MySQL 只读副本机制要求两个架构准确无误。

我知道在MySQL中一般可以做到这一点(虽然我不知道具体情况);我想完全在 AWS RDS 框架内完成此操作。

Mic*_*bot 6

问题在于 AWS RDS MySQL 只读副本机制要求两个架构准确无误。

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

但是,如果您对“足够接近”的定义确实足够接近,则可以在 RDS for MySQL 中按照您一贯的方式完成此操作。

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

嗯,这不会是你这样做的方式。

这也不是在 RDS 之外执行此操作的方式。你总是必须从一个相同的副本开始,然后更改它,因为复制根据定义依赖于一个已知的、特定的时间点,其中数据集和模式是相同的,之后更改变得可能达到 MySQL 确实认为的程度他们“足够接近”。

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

将表添加到副本中可以,但删除表则不行,甚至可以在表中添加列或删除列,当且仅当从第一列开始按顺序位置排列的其余列相同时。也就是说,您可以在表的右边缘添加列或从右边缘删除列;您无法更改列顺序,但如果可以进行强制转换,则可以更改数据类型,例如增加VARCHAR. 只要将BINLOG_FORMAT主服务器上的 on 设置为 ,您就可以重命名列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 会使用正常锁定机制(如表元数据锁)自动暂停复制事件的执行活动需要访问权限。

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


问题: loooonngggg 的更改(重新整理列将花费大约一个小时)会导致 master 出现问题吗?我正在考虑大量备份的复制日志,以及在只读副本中的锁上阻塞一小时的流量。

对于 RDS,这不会成为问题,原因有两个。

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

此外,尽管在这种情况下意义不大,但由于 I/O 线程将保持运行,RDS 不会使用标准expire_logs_days系统变量从主服务器中清除旧的二进制日志。相反,它会在您的副本不再需要它们时自行清除它们,但在此之前不会清除它们,这很有帮助,因为它们会占用您的存储分配。(如果需要,您还可以配置 RDS 将它们保留更长时间)。我已完全停止 RDS 复制超过 24 小时,然后重新启动,没有出现任何问题。