如何重新同步AWS RDS只读副本

时间:2019-02-06 13:47:43

标签: amazon-web-services amazon-rds amazon-read-replica

是否有办法修复已停止与主数据库同步的只读副本?由于找不到此答案,我已经在删除它并创建一个新的答案,但是很高兴知道它是否再次发生。

该数据库是带有Innodb表的MySQL数据库。

1 个答案:

答案 0 :(得分:1)

MySQL复制背后的原理很简单:如果从两个相同的数据集开始,并且每次更改一个数据集时都更改了另一个,那么两个数据集将保持相同。这就是MySQL复制的工作方式-您从两台完全相同的服务器开始,要么完全空白,要么一台是另一台的精确快照,然后复制仅在两台服务器上执行相同的操作。

复制是通过 binary log (“ binlog”)完成的,该日志将所有更改捕获到主数据库。在标准MySQL异步复制(如RDS中所用)中,副本具有两个特定于目的的线程,即I / O线程,该线程连接到主数据库并从主数据库的binlog捕获复制事件,并将它们写入一个临时存储区,称为中继日志,以及从中继日志中读取并将更改应用到副本的SQL线程。

在副本上,查询SHOW SLAVE STATUS;将告诉您这两个线程是否正在运行。如果它们正在运行,则该副本运行状况良好,尽管它可能位于主副本之后,也可以从该查询的输出中找到的值Seconds_Behind_Master来证明。否则,您将发现遇到的错误,从而导致一个或另一个线程停止。

理论上,除非发生以下三种情况之一,否则MySQL副本将永远不会不同步:

  • 您应该做一些不应该做的事情,以使副本与母版不一致-例如使副本可写,然后对其进行写入。
  • MySQL源代码中存在一个导致不一致的错误
  • 副本与主服务器断开连接的时间足够长,以致于主服务器已经丢弃了副本从未见过的某些复制事件。

第一个问题将导致SQL线程停止,因为它试图应用无意义的更改-通常删除不存在的行,更新不存在或不匹配的行,插入行已经存在,等等。

第二个问题可能会导致IO线程或SQL线程出现问题,但是这种情况很少见。

最后一个问题将导致IO线程停止运行,因为它会记住在主服务器上留下的位置,并且如果此时主服务器上没有二进制日志文件可用,则将陷入僵局。 RDS应该通过将日志保留在主数据库上,直到所有托管副本都已捕获它们来防止这种情况。

因此, general 答案是,您可以通过基于主节点的状态将其所有数据完全置于应处于的状态来修复MySQL只读副本。复制SQL线程当前指向的时间(在中继日志中)。

在RDS中,这有点棘手,因为您没有SUPER特权,但是仍然可以。还是...

tl; dr:复制损坏只是一种症状-您必须弄清楚实际的问题是什么。

您需要能够找出问题所在,并采取措施进行纠正。问题是,复制停止后,除非您对所发生的事情有非常清楚的了解,否则您实际上并不知道副本上可能有多糟糕。

回想一下上面提到的原理-从两个相同的数据集开始,每次更改一个数据集,都更改另一个-接下来要注意的是MySQL没有任何内置机制来确保一致性在没有实际复制错误的情况下。两台服务器可能会大相径庭,但复制会愉快地继续,直到SQL线程遇到无法复制的内容为止。您需要一个第三方实用程序来比较两个服务器上的数据并找出任何差异。

如果您清楚地了解出了什么问题,可以暂时使副本可写(使用read_only系统变量的参数组设置),进行更正更改,然后重新启动复制。在RDS上,由于您没有SUPER特权,因此只能通过重新引导副本在当前事件指针处重新启动,或者可以将副本置于应在之后< / em>复制有问题的事件,然后使用CALL mysql.rds_skip_repl_error();使用它们为此提供的解决方法。 请勿在不了解其作用的情况下使用此操作-具体来说,它会忽略故障并继续进行下一个事件,除非您手动使副本保持一致,否则绝对会使副本处于不一致状态。当保留副本当前状态比保持副本正确状态更为重要时,应仅将其保留用于紧急情况,因为跳过错误本质上保证了将来会有更多错误。

修复副本不是一件容易的事。这是经验丰富的DBA的任务。在RDS中,最好的选择通常是丢弃该副本并创建一个新副本,但是由于复制错误永远不会发生-这不是您必须要做的事情。如果这样做,则需要找出原因。