如何使用MySQL主控主机复制处理唯一索引

时间:2016-03-11 10:15:39

标签: mysql replication mariadb unique-index

如何在主 - 主动 - 主动复制环境中处理UNIQUE索引?

SQL架构示例:

CALLS
  id INTEGER PRIMARY AUTO_INCREMENT
  caller_id INTEGER + INDEX
  start_date datetime
  end_date datetime
  ...

CALLERS
  id INTEGER PRIMARY AUTO_INCREMENT
  phone VARCHAR UNIQUE
  country_id CHAR(2)
  city_id INTEGER
  ...

在负载较重(很多插入)环境中,请求可以发送到两个主服务器(用于perf,高可用性,0停机模式更改原因)。

如果两个主人同时创建2个CALLERS记录(是的,可以):

  • 在复制模式=行中,复制会因DUPLICATE事件而中断
  • 在复制模式=具有ON DUPLICATE KEY UPDATE的行中,复制也会中断(因为ON DUPLICATE KEY UPDATE未应用于相对的主服务器上)

  • 在复制模式=语句中,复制也会中断

  • 在具有ON DUPLICATE KEY UPDATE的复制模式=语句中,复制继续工作......但我们可能会有不一致的记录:

    如果两个主人同时创建2个CALLERS,

    • master1.CALLERS.id = 1 masters1.CALLS.caller_id = 1
    • master2.CALLERS.id = 2 master2.CALLS.caller_id = 2
    • 两个master上的
    • ,一旦被复制,复制的CALLS记录将有一个指向不存在的记录的caller_id列

处理这个非常简单的案例的最佳解决方案是什么?

我想过像这样的解决方案,但它们有很大的缺点

  • 在这些情况下,不要通过合并CALLERS和CALLS表来使用UNIQUE索引,但这是一个巨大的功能损失......并继续使用基于ROW的复制。但是:

    • 这不适用于所有UNIQUE索引案例!
  • 不要使用AUTO_INCREMENT(不要让MySQL选择id值),但是:

    • 如果没有SPOF并且没有性能下降,您将如何生成其他唯一值? (可能适合4字节列的内容​​)
    • 必须更改所有应用程序(真实应用程序中的超过一百个表)

1 个答案:

答案 0 :(得分:1)

使用标准复制的多主机提高写入性能 - 所有写入必须应用于所有主机。

带有标准复制的多主机在UNIQUEPRIMARY键方面存在许多问题。这是大多数人避免给两位大师的主要原因。

AUTO_INCREMENT通常可以通过使用auto_increment_increment =主数量来设置问题,auto_increment_offset设置为不同的值(1,2,..)。这就是加莱拉在幕后所做的事情。

ROWSTATEMENT - 不应有任何区别。

Galera有很多优点,特别是如果你有至少3个节点。特别是因为HA是一个目标。

你有很多INSERTs?它们是单行还是批量或LOAD DATA?单行比任何其他行都慢得多(在任何情况下)。在所有情况下,您都必须检查错误。在某些情况下,您可能会遇到“死锁”和“回滚”,需要重播事务。

小心IGNORE选项 - 它可以“刻录”auto_increment id。 More discussion

另见Techniques for really high speed ingestion。也许你可以在一台机器上获得足够的速度。

旁注:country_id CHAR(2)应为CHARACTER SET ascii;使用utf8它将始终占用6个字节。

相关问题