mysql - M-M 主动 mysql 复制如何处理唯一键值

标签 mysql database-administration

主-主双活mysql复制如何处理唯一键值。 对于主键值,我们可以设置 auto_increment_increment 和 auro_increment_offset 参数以避免主键 auto_increment 冲突。 但类似地,这里如何处理唯一的键约束?

最佳答案

答案很简单:它处理它们。

由于复制是异步的,因此您有可能导致 split-brain errors如果同时写入主-主复制集群的两个节点。也就是说,您可以在两个复制节点上成功插入,但是当副本重播另一个复制节点的插入时,会导致冲突,因为副本已经插入了具有冲突值的行。

外键约束也会出现类似的问题。例如,您可以插入带有引用另一个表中的父行的 FK 的行,即使同时有人删除了其他节点中的该父行。当复制这两个更改时,会导致错误。

如果您在触发器中实现了更复杂的约束,则可以创建相同的效果。例如,假设您编写了一个触发器,仅当表中至少还剩下 5 行时才允许您从表中删除行。您删除一行,触发器允许这样做。但随后该节点从另一个节点复制删除操作,导致表中只剩下 4 个节点的无效状态。

以下是防止裂脑错误的几种方法:

  1. 仅允许在一个节点上写入,至少对于具有 UNIQUE KEY 或 FOREIGN KEY 或其他可能导致裂脑风险的给定表。这是最常见的解决方案,通常将其中一个节点设置为全局只读(不仅针对一张表,而是针对整个实例)。

  2. 使用某种全局信号量来“锁定”对给定表的访问。信号量指定哪个节点允许写入表,并且连接到副本集的所有应用程序都必须遵守该信号量。您可以更改信号量,但必须先将一个节点上所做的所有更改复制到另一节点上。但这违背了允许在多个节点上并发写入的目标。

  3. 强制同步复制。也就是说,当存在待处理的复制更改时,您无法对节点进行任何更改。 Galera Cluster 有一种模式,在该模式下,节点上的本地更改(甚至 SELECT 语句)必须等到所有挂起的二进制日志都已播放完毕。

  4. 使所有写入异步但有序。不要直接写入数据库,而是写入消息队列,然后让一个后端处理器按串行顺序使用该队列,应用更改。这仍然可能导致错误,例如不允许 DELETE 将表减少到少于 5 行的示例。但至少不会是裂脑错误。

关于mysql - M-M 主动 mysql 复制如何处理唯一键值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55092995/

相关文章:

php - 如何在 Heroku 中将 Mysql 命令与 ClearDB 一起使用?

Mysql 跨表多个唯一键

mysql - 在 NodeJS 中读取存储在磁盘中的 .sql 数据库作为文件

oracle - Oracle SYS和SYSTEM帐户有什么区别?

database - PostgreSQL : noInherit not working?

mysql - MySql 中基于 IF EXISTS 的条件 SELECT

Python 和 MySQL 更新

database - 如何从主主机获取备用主机名

mysql - 在远程 mysql 数据库上执行脚本?

linux - 连接 Postgres Db : Server Certificate Does Not Match Host Name 时出错