几周前,我启动了一个 RDS Aurora AZ 实例。它自动创建了两个实例:一个主实例和一个只读副本。
上周我使用 mysql 命令行界面登录到主 mysql 实例,并成功创建了一个新表。今天,我使用 mysql 命令行界面登录到主 mysql 实例,尝试进行更改,但收到一条错误消息,提示数据库是只读的。然后我查看了 AWS RDB 控制台,发现主数据库和副本数据库已切换。主数据库是只读的,副本数据库是写入器。
我大约 2 小时前就注意到了这一点,情况没有改变。所以这不是因为维护窗口(因为维护窗口只有 30 分钟)。
为什么会发生这种情况?我应该做些什么来防止将来再次发生这种情况?
答案1
他们可能因为维护而更换了。等待升级至 Aurora 1.7.1(日期:2016-09-20)现在显示我的一个 Aurora 集群(2016-10-15,SELECT @@AURORA_VERSION;
显示 1.6)。如果先升级副本,然后触发故障转移事件,然后升级主服务器,那么这样做是有道理的,但我猜测——我在文档中找不到对此的明确说明。
或者,原始主服务器可能发生了故障,从而导致故障转移,随后恢复原始主服务器。
无论如何,你都应该找到证据某物在实例事件日志中,假设它是最近的 - 请参阅 RDS 控制台左侧的“事件”。
但至于他们为什么转换了然后又没有转换回来,这是一个可能更容易回答的问题——我不认为有理由指望他们会转换回来。
在任何时间点,您的一个实例都是“主实例”——但与 MySQL/MariaDB 本机复制不同,称其为“主实例”并不准确,因为 Aurora 集群中的实例都共享一个公共的后备存储——它们没有单独的数据副本,它们都是访问共享和复制的存储后端的对等实例。与主实例和从属实例/副本不同,其中一个实例是作家(可以读取和写入)和其他(如果它们存在,则单个实例“集群”有效)是读者(只读),但任何一个实例都可能由于故障转移事件(可能由于实际故障以外的原因触发)而成为写入者。可以对实例进行优先级排序,以便故障转移导致切换到首选实例(Aurora 集群中的实例不必是同一实例类),但这似乎仅在节点数大于两个时才有意义。
但从根本上来说,Aurora 的设计似乎是这样的:您不应该将您的实例视为其中某个特定的实例是主实例……并且基础设施提供了一种让其不重要的方法。
Aurora 集群具有由您指定的集群名称和由系统指定的字母数字集群标识符,并且集群中的每个实例都具有由您指定的名称。
Aurora 与 RDS 的标准行为一样,会根据您为实例指定的名称和集群标识符在 DNS 中为每个实例创建一个主机名,但 Aurora 集群会创建两个额外的主机名 - 一个将您连接到写入器,另一个将您连接到其中一个读取器(或者,当集群只有一个成员时,它还会将您连接到集群的唯一成员,该成员实际上是写入器)。
假设您的集群名称是prod-db
,假设您的系统分配的标识符是xyzzyexample
,假设您创建的节点名为...node-1
并且node-2
区域是us-east-1
。
实例主机名如下所示:
node-1.xyzzyexample.us-east-1.rds.amazonaws.com # instance 1
node-2.xyzzyexample.us-east-1.rds.amazonaws.com # instance 2
但是您用来访问 Aurora 的主机名不是这些。
您应该使用的那些,除非您有特殊的理由不这样做,例如将作业固定到特定副本,如下所示:
prod-db.cluster-xyzzyexample.us-east-1.rds.amazonaws.com # writer
prod-db.cluster-ro-xyzzyexample.us-east-1.rds.amazonaws.com # reader
这些是在 DNS 中作为 CNAME 实现的,由 RDS 管理,因此每次连接时,您都会得到适合您集群当前配置的答案。写入器地址的 TTL 为 5 秒,读取器地址的 TTL 为 1 秒,因此答案正确的几率相当高。通过使用这些地址进行连接,您不必担心机器切换角色。