我有两台服务器以双主服务器方式运行 mysql(每台服务器都是主服务器,每台服务器都是从服务器)。在对峰值负载期间可能出现的问题进行故障排除时,我开始想知道 mysql 如何防止在这种关系中出现命令“循环”。
我的具体问题是:
如果 A 是从属于 B 的,并且 B 是从属于 A 的,那么什么会阻止在 A 上执行的 SQL 命令通过它们的主(A)->从(B)关系传播到 B,然后再通过主(B)->从(A)关系进一步传播回 A?
我的猜测是,除了命令本身之外,还存在某种传递的命令的唯一标识,这样 A 就知道它之前已经执行过该命令(可能是使用该server-id
选项)。但是,我今天的谷歌能力太弱了,无法找出幕后工作原理。
Read_Master_Log_Pos
以下是这与我的问题的关系。每 5 分钟,我都会看到和之间出现滞后Exec_Master_Log_Pos
。我了解这种情况的基本原因 - 我相信应用程序配置为以五分钟为间隔将大量数据转储到数据库(事实上,在绘制值之间的 15 秒增量时,我推测每 5 分钟有固定数量的跑步者,每 15 分钟设置更多,每 30 分钟设置更多)。
不过,我真正担心的是两个从服务器都出现了相同的延迟。我对此应用程序设计的理解是,除非该服务器不可用,否则将始终使用“活动”(从应用程序角度,而不是从 mysql 角度)数据库服务器,在这种情况下,应用程序将尝试使用“备用”数据库服务器。如果这是真的,为什么我在两个从服务器上都看到读取/执行延迟?如果不是真的,我是否对应用程序架构存在根本性的误解,或者“活动”服务器是否被过度使用,以至于应用程序正在自行故障转移,即使服务器从未“关闭”?(最后两个不是 SF 问题,只是我正在努力回答的问题)
我读到,mysql 主/从关系中的主服务器相当简单,因为它将所有内容发送给从服务器,由从服务器决定执行哪些命令(如果有)。如果是这样的话,我在从服务器到备用服务器看到的延迟可能是由于所有那些已经执行的命令都被拉下来,并且必须评估这些命令是否已经执行过而导致的。
答案1
就您的具体问题而言,它是两件事的结合:
- 默认情况下,如果服务器通过复制收到一条语句,它不会将同一条语句发送给其从属服务器,从而防止出现任何类型的循环。但是,可以更改此设置(通过
log-slave-updates
在 my.cnf 中添加“ ”),从而导致: - 在复制过程中,它会随语句一起发送原始服务器的服务器 ID。如果某个服务器通过复制收到具有相同服务器 ID 的语句,它将不会执行该语句,从而防止其重复执行相同的语句。
答案2
使用 mysql-master-master 只有在一般情况下才是真正安全的
- 每次只能写入一台服务器
- 当你从一台服务器切换到另一台服务器时,你需要等待复制提前完成
如果你确信你会这么做,那很好。
如果您的应用程序在编写时非常谨慎,考虑到它在 mysql-master-master 上运行的事实(例如,对唯一索引非常小心 - 确保您在其他服务器上没有密钥冲突),那么您可能没问题。我无法轻松编写这样的应用程序。
当然,mysql-master-master 对于提高写入性能没有用,因为两个服务器也需要执行所有写入操作。