使用MySQL组复制的限制和局限性

本节列出和解释了组复制相关的要求和限制。html

1.组复制的要求

要使用组复制,每一个MySQL节点必须知足如下条件:mysql

1.1 基本要求

  1. InnoDB存储引擎:数据必须存储在事务型的InnoDB存储引擎中。事务以乐观形式执行,而后在提交前会检测冲突问题。若是有冲突,为了维护组中一致性,有些事务必须回滚。这意味着须要事务型的存储引擎。此外,InnoDB 存储引擎提供了一些额外的功能,它们结合组复制时能更好地管理和处理冲突。
  2. Primary Keys:每张须要被组复制的表都必须显式定义一个主键。主键在判断事务是否冲突扮演极其重要的角色:经过主键来准确识别每一个事务中修改了表中的哪些行。(其实是将主机hash成写集,而后由certifier来并发事务之间的检测冲突性)
  3. 使用IPv4 地址:MySQL组复制使用的组通讯引擎组件只支持 IPv4。所以,必须使用IPv4的网络。
  4. 良好的网络性能:组复制设计的初衷是部署在集群环境中,集群中的节点相互之间都很是近,所以除了网络延迟,网络带宽也会影响组复制。

1.2 配置上的要求

组中的每一个成员都必须配置如下选项:sql

  1. 必须开启二进制日志:设置--log-bin[=log_file_name]。MySQL组复制会复制二进制日志的内容,所以必须开启二进制日志。
  2. Slave Updates Logged:设置--log-slave-updates。节点须要记录applier已应用的日志。组中的每一个节点都须要记录它们所接收到并应用的全部事务,这是必须的,由于恢复过程是依赖于组中参与者的二进制日志来进行的。所以,组中每一个成员都必须保留每一个事务的副本,即便某事务不是在该节点上开始的。
  3. Row Format的二进制日志:设置--binlog-format=row。组复制依赖于基于行格式的二进制日志,以便在组中传播所发生的更改能保持一致性。并且,在探测组中不一样节点间发生的并发事务是否冲突时,须要从行格式的日志中提取一些内容来作比较。
  4. 开启GTID复制:设置--gtid-mode=ON。组复制使用GTID(全局事务ID)来精确跟踪每一个节点上已经提交了哪些事务。也所以能够推断出某节点上要执行的事务是否和已执行的事务(每一个节点上都有副本)冲突。换句话说,GTID是整个组复制判断事务是否冲突的基础。
  5. Replication Information Repositories:设置--master-info-repository=TABLE--relay-log-info-repository=TABLE。applier须要将 master 和 relay log 的元数据信息写入到系统表 mysql.slave_master_infomysql.slave_relay_log_info 中。这保证了组复制插件具备一致性恢复的能力和复制的元数据事务管理能力。
  6. Transaction Write Set Extraction:设置--transaction-write-setextraction=XXHASH64,以便将行写入到二进制日志中时,节点也收集写集。写集基于每行的主键,是惟一标识被更改行的标签的简化形式,该标签后续会用于探测事务冲突性。
  7. Multithreaded Appliers:(某些旧版本没有该要求)能够将组复制成员配置为多线程appliers,使得能够并行应用事务。须要设置--slave-parallel-workers=N(N是applier线程数量)、--slavepreserve-commit-order=1以及--slave-parallel-type=LOGICAL_CLOCK--slaveparallel-workers=N表示启用多applier线程,组复制依赖于创建在全部参与节点都以相同顺序接收和应用、提交事务的一致性机制,所以还必须设置--slave-preserve-commit-order=1以保证并行事务的最终提交是和原事务所在顺序位置一致的。最后,为了决定哪些事务能够并行执行,relay log 必须包含由--slave-parallel-ype=LOGICAL_CLOCK生成的事务父信息(transaction parent information)。当尝试加入一个只设置了--slave-parallel-workers大于0,却没有设置其余两项的新成员,将会报错并阻止它的加入。

2.组复制的限制(局限性)

下面是使用组复制已知的限制:网络

  1. Replication Event Checksums:因为对复制事件校验的设计缺陷,目前组复制不能使用它们。所以,须要设置--binlog-checksum=NONE
  2. Gap Locks:在验证阶段中(certification process),不会考虑 Gap Locks,所以在 InnoDB 的外部没法获取任何关于Gap 锁的信息。多线程

    注意:并发

    除非你的应用程序或业务需求依赖于REPEATABLE READ(MySQL默认该隔离级别),不然建议在组复制中使用READ COMMITTED隔离级别。在READ COMMITTED隔离级别中,InnoDB基本上不会使用Gap Locks,这将使得InnoDB自带的冲突探测能和组复制的冲突探测相互对齐从而保持一致。app

  3. Table Locks and Named Locks:验证阶段(certification process)中不考虑表锁和命名锁(见get_lock())。
  4. 不支持 SERIALIZABLE 隔离级别:在多主模型下,默认不支持该隔离级别。若是在多主模型下设置了该隔离级别,将拒绝提交事务。
  5. 不支持并发的 DDL 和 DML 操做:不支持在多主模型下不一样节点上同时执行DDL和DML修改同一对象。在某节点上对某对象执行DDL语句时,若是在其余节点同时执行DML修改该对象,将有必定风险探测到冲突。(译注:是 DDL+DML 的并发,DDL+DDL 的并发也不容许。这是由于MySQL中没有DDL事务,不能保证DDL的原子性,当DDL和DML同时操做某一个对象,可能DDL修改后,DML将由于对象结构的改变而没法执行,继而回滚)
  6. 不支持级联的外键约束:多主模型的组(全部节点都配置了group_replication_single_primary_mode=OFF)不支持多级外键依赖,特别是表上定义了级联的外键约束(CASCADING foreign key constraints)。这是由于多主模型下执行外键约束的级联操做可能会出现未检测到的冲突,从而致使组内成员间数据不一致。所以,咱们推荐在使用多主模型时,在每一个节点上都设置group_replication_enforce_update_everywhere_checks=ON以免出现未检测到的冲突。在单主模型下没有这种问题,由于没有并发写操做,从而不可能会出现未被探测到的冲突。
  7. 大事务可能会错误:若是一个事务很是大,致使GTID的内容很是多,以致于没法在 5 秒内经过网络传输完成,这时组成员间的通讯将失败。要避免该问题,能够尽量地限制事务的大小。例如,将LOAD DATA INFILE的文件切割为多个小块。
  8. 多主模型可能出现死锁:在多主模型下,SELECT ... FOR UPDATE语句可能会致使死锁。这是由于组内成员之间不会共享锁资源(译注:share nothing),所以这样的语句可能达不到预期的结果。性能

相关文章
相关标签/搜索