MySQL8 中文参考(八十一)(1)https://developer.aliyun.com/article/1566072
当 s2 尝试加入组时,第 20.5.4 节,“分布式恢复” 确保 s2 应用了与 s1 应用的相同事务。一旦此过程完成,s2 可以作为成员加入组,并在此时标记为ONLINE
。换句话说,它必须已经自动赶上了服务器 s1。一旦 s2 处于ONLINE
状态,它就开始与组处理事务。验证 s2 是否已经与服务器 s1 同步如下。
mysql> SHOW DATABASES LIKE 'test'; +-----------------+ | Database (test) | +-----------------+ | test | +-----------------+ mysql> SELECT * FROM test.t1; +----+------+ | c1 | c2 | +----+------+ | 1 | Luis | +----+------+ mysql> SHOW BINLOG EVENTS; +---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+ | binlog.000001 | 4 | Format_desc | 2 | 123 | Server ver: 8.0.36-log, Binlog ver: 4 | | binlog.000001 | 123 | Previous_gtids | 2 | 150 | | | binlog.000001 | 150 | Gtid | 1 | 211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1' | | binlog.000001 | 211 | Query | 1 | 270 | BEGIN | | binlog.000001 | 270 | View_change | 1 | 369 | view_id=14724832985483517:1 | | binlog.000001 | 369 | Query | 1 | 434 | COMMIT | | binlog.000001 | 434 | Gtid | 1 | 495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2' | | binlog.000001 | 495 | Query | 1 | 585 | CREATE DATABASE test | | binlog.000001 | 585 | Gtid | 1 | 646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3' | | binlog.000001 | 646 | Query | 1 | 770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) | | binlog.000001 | 770 | Gtid | 1 | 831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4' | | binlog.000001 | 831 | Query | 1 | 890 | BEGIN | | binlog.000001 | 890 | Table_map | 1 | 933 | table_id: 108 (test.t1) | | binlog.000001 | 933 | Write_rows | 1 | 975 | table_id: 108 flags: STMT_END_F | | binlog.000001 | 975 | Xid | 1 | 1002 | COMMIT /* xid=30 */ | | binlog.000001 | 1002 | Gtid | 1 | 1063 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:5' | | binlog.000001 | 1063 | Query | 1 | 1122 | BEGIN | | binlog.000001 | 1122 | View_change | 1 | 1261 | view_id=14724832985483517:2 | | binlog.000001 | 1261 | Query | 1 | 1326 | COMMIT | +---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
如上所示,第二个服务器已添加到组中,并且已自动复制了来自服务器 s1 的更改。换句话说,应用在 s1 上直到 s2 加入组的时间点的事务已经复制到 s2。
20.2.1.6.2 添加额外实例
将额外的实例添加到组中本质上与添加第二个服务器的步骤相同,只是配置必须像对服务器 s2 进行配置一样进行更改。总结所需的命令如下:
- 创建配置文件。
[mysqld] # # Disable other storage engines # disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY" # # Replication configuration parameters # server_id=3 gtid_mode=ON enforce_gtid_consistency=ON binlog_checksum=NONE # Not needed from 8.0.21 # # Group Replication configuration # plugin_load_add='group_replication.so' group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" group_replication_start_on_boot=off group_replication_local_address= "s3:33061" group_replication_group_seeds= "s1:33061,s2:33061,s3:33061" group_replication_bootstrap_group= off
- 启动服务器并连接到它。为分布式恢复创建复制用户。
SET SQL_LOG_BIN=0; CREATE USER *rpl_user*@'%' IDENTIFIED BY '*password*'; GRANT REPLICATION SLAVE ON *.* TO *rpl_user*@'%'; GRANT CONNECTION_ADMIN ON *.* TO *rpl_user*@'%'; GRANT BACKUP_ADMIN ON *.* TO *rpl_user*@'%'; GRANT GROUP_REPLICATION_STREAM ON *.* TO *rpl_user*@'%'; FLUSH PRIVILEGES; SET SQL_LOG_BIN=1;
- 如果您正在使用
CHANGE REPLICATION SOURCE TO
|CHANGE MASTER TO
语句提供用户凭据,请在此之后发出以下语句:
CHANGE MASTER TO MASTER_USER='*rpl_user*', MASTER_PASSWORD='*password*' \\ FOR CHANNEL 'group_replication_recovery'; Or from MySQL 8.0.23: CHANGE REPLICATION SOURCE TO SOURCE_USER='*rpl_user*', SOURCE_PASSWORD='*password*' \\ FOR CHANNEL 'group_replication_recovery';
- 如有必要,安装组复制插件。
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
- 启动组复制。
mysql> START GROUP_REPLICATION;
- 或者,如果您正在为分布式恢复提供用户凭据,可以在
START GROUP_REPLICATION
语句中执行此操作(从 MySQL 8.0.21 开始):
mysql> START GROUP_REPLICATION USER='*rpl_user*', PASSWORD='*password*';
此时服务器 s3 已经启动并运行,已加入组并赶上了组内其他服务器的进度。再次查看performance_schema.replication_group_members
表可以确认这一点。
mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+ | group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 | s1 | 3306 | ONLINE | PRIMARY | 8.0.27 | XCom | | group_replication_applier | 7eb217ff-6df3-11e6-966c-00212844f856 | s3 | 3306 | ONLINE | SECONDARY | 8.0.27 | XCom | | group_replication_applier | ac39f1e6-6dfa-11e6-a69d-00212844f856 | s2 | 3306 | ONLINE | SECONDARY | 8.0.27 | XCom | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
在服务器 s2 或服务器 s1 上发出相同的查询会得到相同的结果。此外,您可以验证服务器 s3 已经赶上:
mysql> SHOW DATABASES LIKE 'test'; +-----------------+ | Database (test) | +-----------------+ | test | +-----------------+ mysql> SELECT * FROM test.t1; +----+------+ | c1 | c2 | +----+------+ | 1 | Luis | +----+------+ mysql> SHOW BINLOG EVENTS; +---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+ | binlog.000001 | 4 | Format_desc | 3 | 123 | Server ver: 8.0.36-log, Binlog ver: 4 | | binlog.000001 | 123 | Previous_gtids | 3 | 150 | | | binlog.000001 | 150 | Gtid | 1 | 211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1' | | binlog.000001 | 211 | Query | 1 | 270 | BEGIN | | binlog.000001 | 270 | View_change | 1 | 369 | view_id=14724832985483517:1 | | binlog.000001 | 369 | Query | 1 | 434 | COMMIT | | binlog.000001 | 434 | Gtid | 1 | 495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2' | | binlog.000001 | 495 | Query | 1 | 585 | CREATE DATABASE test | | binlog.000001 | 585 | Gtid | 1 | 646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3' | | binlog.000001 | 646 | Query | 1 | 770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) | | binlog.000001 | 770 | Gtid | 1 | 831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4' | | binlog.000001 | 831 | Query | 1 | 890 | BEGIN | | binlog.000001 | 890 | Table_map | 1 | 933 | table_id: 108 (test.t1) | | binlog.000001 | 933 | Write_rows | 1 | 975 | table_id: 108 flags: STMT_END_F | | binlog.000001 | 975 | Xid | 1 | 1002 | COMMIT /* xid=29 */ | | binlog.000001 | 1002 | Gtid | 1 | 1063 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:5' | | binlog.000001 | 1063 | Query | 1 | 1122 | BEGIN | | binlog.000001 | 1122 | View_change | 1 | 1261 | view_id=14724832985483517:2 | | binlog.000001 | 1261 | Query | 1 | 1326 | COMMIT | | binlog.000001 | 1326 | Gtid | 1 | 1387 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:6' | | binlog.000001 | 1387 | Query | 1 | 1446 | BEGIN | | binlog.000001 | 1446 | View_change | 1 | 1585 | view_id=14724832985483517:3 | | binlog.000001 | 1585 | Query | 1 | 1650 | COMMIT | +---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
20.2.2 本地部署组复制
原文:
dev.mysql.com/doc/refman/8.0/en/group-replication-deploying-locally.html
部署组复制最常见的方式是使用多个服务器实例,以提供高可用性。也可以在本地部署组复制,例如用于测试目的。本节解释了如何在本地部署组复制。
重要
组复制通常部署在多个主机上,因为这样可以提供高可用性。本节中的说明不适用于生产部署,因为所有 MySQL 服务器实例都在同一台主机上运行。如果此主机发生故障,整个组都会失败。因此,此信息应仅用于测试目的,不应在生产环境中使用。
本节解释了如何在一台物理机器上创建一个包含三个 MySQL 服务器实例的复制组。这意味着需要三个数据目录,每个服务器实例一个,并且需要独立配置每个实例。此过程假定 MySQL 服务器已下载并解压缩到名为mysql-8.0
的目录中。每个 MySQL 服务器实例都需要一个特定的数据目录。创建一个名为data
的目录,然后在该目录中为每个服务器实例创建一个子目录,例如s1
、s2
和s3
,并对每个实例进行初始化。
mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s1 mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s2 mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s3
在data/s1
、data/s2
、data/s3
中是一个已初始化的数据目录,包含 mysql 系统数据库和相关表等等。要了解更多关于初始化过程的信息,请参见第 2.9.1 节,“初始化数据目录”。
警告
在生产环境中不要使用-initialize-insecure
,这只是为了简化教程而使用的。有关安全设置的更多信息,请参见第 20.6 节,“组复制安全”。
本地组复制成员的配置
当您按照第 20.2.1.2 节,“为组复制配置实例”时,您需要为前一节添加的数据目录添加配置。例如:
[mysqld] # server configuration datadir=<full_path_to_data>/data/s1 basedir=<full_path_to_bin>/mysql-8.0/ port=24801 socket=<full_path_to_sock_dir>/s1.sock
这些设置配置了 MySQL 服务器使用之前创建的数据目录以及服务器应该打开和开始监听传入连接的端口。
注意
本教程中使用非默认端口 24801,因为三个服务器实例使用相同的主机名。在三台不同机器的设置中,这是不需要的。
组复制需要成员之间的网络连接,这意味着每个成员必须能够解析所有其他成员的网络地址。例如,在本教程中,所有三个实例都在一台机器上运行,因此为了确保成员之间可以联系,您可以在选项文件中添加一行,例如report_host=127.0.0.1
。
然后,每个成员需要能够连接到其他成员的group_replication_local_address
。例如,在成员 s1 的选项文件中添加:
group_replication_local_address= "127.0.0.1:24901" group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
这将配置 s1 使用端口 24901 进行与种子成员的内部组通信。对于要添加到组中的每个服务器实例,请在成员的选项文件中进行这些更改。对于每个成员,您必须确保指定了唯一地址,因此对于group_replication_local_address
,每个实例使用唯一端口。通常,您希望所有成员都能够作为加入组并且尚未通过组处理事务的成员的种子,因此,请像上面显示的那样将所有端口添加到group_replication_group_seeds
。
第 20.2.1 节,“在单主模式下部署组复制”的其余步骤同样适用于您以这种方式在本地部署的组。
20.3 需求和限制
原文:
dev.mysql.com/doc/refman/8.0/en/group-replication-requirements-and-limitations.html
20.3.1 集群复制需求
20.3.2 集群复制限制
本节列出并解释了集群复制的需求和限制。
20.3.1 Group Replication Requirements
原文:
dev.mysql.com/doc/refman/8.0/en/group-replication-requirements.html
- 基础设施
- 服务器实例配置
您希望用于 Group Replication 的服务器实例必须满足以下要求。
基础设施
- InnoDB 存储引擎。 数据必须存储在
InnoDB
事务性存储引擎中。事务乐观执行,然后在提交时检查冲突。如果存在冲突,为了在组内保持一致性,一些事务将被回滚。这意味着需要一个事务性存储引擎。此外,InnoDB
提供了一些额外功能,使其在与 Group Replication 一起操作时能更好地管理和处理冲突。使用其他存储引擎,包括临时MEMORY
存储引擎,可能会导致 Group Replication 中的错误。在将实例与 Group Replication 一起使用之前,请将任何其他存储引擎中的表转换为使用InnoDB
。您可以通过在组成员上设置disabled_storage_engines
系统变量来阻止使用其他存储引擎,例如:
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
- 主键。 每个要被组复制的表必须有一个定义好的主键,或者等效的主键,其中等效主键是一个非空唯一键。这些键被要求作为表中每一行的唯一标识符,使系统能够通过确定每个事务修改了哪些行来确定哪些事务发生了冲突。组复制有自己内置的主键或主键等效的检查,不使用
sql_require_primary_key
系统变量执行的检查。您可以在运行组复制的服务器实例上设置sql_require_primary_key=ON
,并且您可以为组复制通道设置CHANGE REPLICATION SOURCE TO
|CHANGE MASTER TO
语句的REQUIRE_TABLE_PRIMARY_KEY_CHECK
选项为ON
。但是,请注意,您可能会发现一些在组复制内置检查下允许的事务,在设置sql_require_primary_key=ON
或REQUIRE_TABLE_PRIMARY_KEY_CHECK=ON
时不被允许。 - 网络性能。 MySQL 组复制被设计用于部署在服务器实例非常接近的集群环境中。组的性能和稳定性可能会受到网络延迟和网络带宽的影响。所有组成员之间必须始终保持双向通信。如果某个服务器实例的入站或出站通信被阻止(例如,由防火墙或连接问题),该成员无法在组中运行,并且组成员(包括存在问题的成员)可能无法报告受影响服务器实例的正确成员状态。
从 MySQL 8.0.14 开始,您可以在远程组复制服务器之间使用 IPv4 或 IPv6 网络基础设施,或两者混合,进行 TCP 通信。组复制也可以在虚拟专用网络(VPN)上运行,没有任何限制。
同样从 MySQL 8.0.14 开始,当组复制服务器实例位于同一位置并共享本地组通信引擎(XCom)实例时,会尽可能使用专用输入通道进行通信,而不是 TCP 套接字,以降低开销。对于某些需要远程 XCom 实例之间通信的组复制任务,比如加入一个组,仍然使用 TCP 网络,因此网络性能会影响组的性能。
服务器实例配置
必须按照以下所示配置的选项在组成员的服务器实例上进行配置。
- 唯一服务器标识符。 使用
server_id
系统变量为服务器配置一个唯一的服务器 ID,这对于复制拓扑中的所有服务器都是必需的。服务器 ID 必须是介于 1 和(2³²)−1 之间的正整数,并且必须与复制拓扑中任何其他服务器使用的任何其他服务器 ID 不同。 - 二进制日志激活。 设置
--log-bin[=log_file_name]
。从 MySQL 8.0 开始,默认情况下启用了二进制日志记录,除非您想更改二进制日志文件的名称,否则不需要指定此选项。组复制会复制二进制日志的内容,因此二进制日志需要处于活动状态才能运行。请参阅第 7.4.4 节,“二进制日志”。 - 复制更新记录。 设置
log_replica_updates=ON
(从 MySQL 8.0.26 开始)或log_slave_updates=ON
(在 MySQL 8.0.26 之前)。从 MySQL 8.0 开始,此设置是默认的,因此您不需要指定它。组成员需要记录从其提供者在加入时接收并通过复制应用程序应用的事务,并记录他们接收并应用于组中的所有事务。这使得组复制能够通过从现有组成员的二进制日志进行状态传输来进行分布式恢复。 - 二进制日志行格式。 设置
binlog_format=row
。这是默认设置,因此您不需要指定它。组复制依赖于基于行的复制格式来在组中的服务器之间一致地传播更改,并提取必要的信息以检测在组中不同服务器上同时执行的事务之间的冲突。从 MySQL 8.0.19 开始,REQUIRE_ROW_FORMAT
设置会自动添加到组复制的通道中,以强制在应用事务时使用基于行的复制。请参阅第 19.2.1 节,“复制格式”和第 19.3.3 节,“复制权限检查”。 - 关闭二进制日志校验和(至 MySQL 8.0.20)。 在 MySQL 8.0.20 及之前的版本中,设置
binlog_checksum=NONE
。在这些版本中,组复制无法使用校验和,并且不支持其存在于二进制日志中。从 MySQL 8.0.21 开始,组复制支持校验和,因此组成员可以使用默认设置binlog_checksum=CRC32
,您不需要指定它。 - 全局事务标识符开启。 将
gtid_mode=ON
和enforce_gtid_consistency=ON
设置为ON
。这些设置不是默认值。基于 GTID 的复制对于 Group Replication 是必需的,它使用全局事务标识符来跟踪已在组中的每个服务器实例上提交的事务。参见第 19.1.3 节,“使用全局事务标识符进行复制”。 - 复制信息存储库。 将
master_info_repository=TABLE
和relay_log_info_repository=TABLE
设置为TABLE
。在 MySQL 8.0 中,这些设置是默认的,FILE
设置已被弃用。从 MySQL 8.0.23 开始,这些系统变量的使用已被弃用,因此省略这些系统变量,只允许默认设置。复制应用程序需要将复制元数据写入mysql.slave_master_info
和mysql.slave_relay_log_info
系统表,以确保 Group Replication 插件具有一致的可恢复性和事务管理的复制元数据。参见第 19.2.4.2 节,“复制元数据存储库”。 - 事务写集提取。 将
transaction_write_set_extraction=XXHASH64
设置为XXHASH64
,以便在收集要记录到二进制日志的行时,服务器也收集写入集。在 MySQL 8.0 中,这是默认设置,从 MySQL 8.0.26 开始,该系统变量的使用已被弃用。写入集基于每行的主键,并且是一个简化且紧凑的视图,用于唯一标识已更改的行。Group Replication 在所有组成员上使用此信息进行冲突检测和认证。 - 默认表加密。 将
default_table_encryption
设置为所有组成员上的相同值。默认模式和表空间加密可以启用(ON
)或禁用(OFF
,默认值),只要所有成员的设置相同即可。 - 表名小写。 将
lower_case_table_names
设置为所有组成员上的相同值。对于使用InnoDB
存储引擎的情况,设置为 1 是正确的,这是 Group Replication 所需的。请注意,这个设置在所有平台上都不是默认值。 - 二进制日志依赖跟踪。 将
binlog_transaction_dependency_tracking
设置为WRITESET
可以根据组的工作负载提高组成员的性能。虽然在应用中继日志中的事务时,组复制在认证后进行自己的并行化,独立于为binlog_transaction_dependency_tracking
设置的任何值,但是这个值确实影响了事务在组复制成员的二进制日志中的写入方式。这些日志中的依赖信息用于协助从捐赠者的二进制日志进行分布式恢复的状态传输过程,每当成员加入或重新加入组时都会发生。
注意
当replica_preserve_commit_order
设置为ON
时,将binlog_transaction_dependency_tracking
设置为WRITESET
与将其设置为WRITESET_SESSION
具有相同的效果。 - 多线程应用程序。 组复制成员可以配置为多线程副本,使事务可以并行应用。从 MySQL 8.0.27 开始,默认情况下所有副本都配置为多线程。系统变量
replica_parallel_workers
(从 MySQL 8.0.26 开始)或slave_parallel_workers
(MySQL 8.0.26 之前)的非零值启用了成员上的多线程应用程序。从 MySQL 8.0.27 开始,默认值为 4 个并行应用程序线程,最多可以指定 1024 个并行应用程序线程。对于多线程副本,还需要以下设置,这些设置是从 MySQL 8.0.27 开始的默认设置:replica_preserve_commit_order=ON
(从 MySQL 8.0.26 开始)或slave_preserve_commit_order=ON
(MySQL 8.0.26 之前)
此设置是为了确保并行事务的最终提交与原始事务的顺序相同。组复制依赖于围绕所有参与成员以相同顺序接收和应用已提交事务的一致性机制构建。replica_parallel_type=LOGICAL_CLOCK
(从 MySQL 8.0.26 开始)或slave_parallel_type=LOGICAL_CLOCK
(MySQL 8.0.26 之前)
此设置需要与replica_preserve_commit_order=ON
或slave_preserve_commit_order=ON
一起使用。它指定了用于决定在副本上允许哪些事务并行执行的策略。
设置replica_parallel_workers=0
或slave_parallel_workers=0
会禁用并行执行,使得复制品只有一个应用程序线程和没有协调器线程。在这种设置下,replica_parallel_type
或slave_parallel_type
以及replica_preserve_commit_order
或slave_preserve_commit_order
选项不起作用,会被忽略。从 MySQL 8.0.27 开始,如果在复制品上使用 GTIDs 时禁用了并行执行,复制品实际上会使用一个并行工作者,以利用在不访问文件位置的情况下重试事务的方法。然而,这种行为对用户不会有任何改变。 - 分离的 XA 事务。 MySQL 8.0.29 及更高版本支持分离的 XA 事务。分离的事务是指一旦准备好,就不再与当前会话连接的事务。这会自动发生作为执行
XA PREPARE
的一部分。准备好的 XA 事务可以由另一个连接提交或回滚,然后当前会话可以启动另一个 XA 事务或本地事务,而无需等待刚刚准备的事务完成。
当启用分离的 XA 事务支持(xa_detach_on_prepare = ON
)时,任何连接到此服务器的连接都可以列出(使用XA RECOVER
)、回滚或提交任何准备好的 XA 事务。此外,在分离的 XA 事务中不能使用临时表。
通过将xa_detach_on_prepare
设置为OFF
可以禁用对分离的 XA 事务的支持,但这并不推荐。特别是,如果此服务器正在设置为 MySQL 组复制中的一个实例,您应该将此变量保持为其默认值(ON
)。
更多信息请参见 Section 15.3.8.2, “XA Transaction States”。
20.3.2 Group Replication 限制
原文:
dev.mysql.com/doc/refman/8.0/en/group-replication-limitations.html
- 组大小限制
- 事务大小限制
Group Replication 存在以下已知限制。请注意,在故障转移事件期间,多主模式组的限制和问题也可能适用于单主模式集群,而新选举的主节点会清空其来自旧主节点的应用程序队列。
提示
Group Replication 是基于 GTID 的复制构建的,因此您还应该注意 Section 19.1.3.7, “使用 GTID 进行复制的限制”。
--upgrade=MINIMAL
选项。 Group Replication 无法在使用 MINIMAL 选项(--upgrade=MINIMAL
)进行 MySQL Server 升级后启动,因为该选项不会升级复制内部所依赖的系统表。- 间隙锁。 Group Replication 的并发事务认证过程不考虑间隙锁,因为间隙锁的信息在
InnoDB
之外不可用。有关更多信息,请参阅间隙锁。
注意
对于多主模式下的组,除非您的应用程序依赖于REPEATABLE READ
语义,我们建议在 Group Replication 中使用READ COMMITTED
隔离级别。 InnoDB 在READ COMMITTED
中不使用间隙锁,这使得 InnoDB 内部的本地冲突检测与 Group Replication 执行的分布式冲突检测保持一致。对于单主模式下的组,只有主节点接受写操作,因此READ COMMITTED
隔离级别对于 Group Replication 并不重要。 - 表锁和命名锁。 认证过程不考虑表锁(参见 Section 15.3.6, “LOCK TABLES 和 UNLOCK TABLES 语句”)或命名锁(参见
GET_LOCK()
)。 - 二进制日志校验和。 截至 MySQL 8.0.20,Group Replication 无法使用校验和,也不支持二进制日志中的校验和,因此在配置服务器实例成为组成员时,必须设置
binlog_checksum=NONE
。从 MySQL 8.0.21 开始,Group Replication 支持校验和,因此组成员可以使用默认设置binlog_checksum=CRC32
。binlog_checksum
的设置不必对组中的所有成员相同。
当校验和可用时,Group Replication 不会使用它们来验证group_replication_applier
通道上的传入事件,因为事件是从多个来源写入到中继日志中的,而在它们实际写入到原始服务器的二进制日志之前,校验和是不会生成的。校验和用于验证group_replication_recovery
通道上的事件的完整性,以及组成员上的任何其他复制通道上的事件。 - 可串行化隔离级别。
SERIALIZABLE
隔离级别在多主组中默认不受支持。将事务隔离级别设置为SERIALIZABLE
会配置 Group Replication 拒绝提交事务。 - 并发 DDL 与 DML 操作。 在使用多主模式时,不支持针对同一对象执行并发数据定义语句和数据操作语句,但在不同的服务器上执行。在对象上执行数据定义语言(DDL)语句期间,在不同服务器实例上执行相同对象的并发数据操作语言(DML)存在冲突的风险,因为在不同实例上执行的冲突 DDL 可能不会被检测到。
- 具有级联约束的外键。 多主模式组(所有成员都配置为
group_replication_single_primary_mode=OFF
)不支持具有多级外键依赖关系的表,特别是定义了CASCADING
外键约束的表。这是因为由多主模式组执行的导致级联操作的外键约束可能导致未检测到的冲突,并导致组成员之间的数据不一致。因此,我们建议在用于多主模式组的服务器实例上设置group_replication_enforce_update_everywhere_checks=ON
以避免未检测到的冲突。
在单主模式下,这不是问题,因为它不允许并发写入到组的多个成员,因此不存在未检测到的冲突风险。 - 多主模式死锁。 当一个组以多主模式运行时,
SELECT .. FOR UPDATE
语句可能导致死锁。这是因为锁不在组的成员之间共享,因此对于这样的语句的期望可能无法实现。 - 复制过滤器。 不能在配置为 Group Replication 的 MySQL 服务器实例上使用全局复制过滤器,因为在某些服务器上过滤事务会导致组无法达成一致状态。可以在与 Group Replication 无直接关系的复制通道上使用特定通道的复制过滤器,例如,当一个组成员同时充当组外源的副本时。不能在
group_replication_applier
或group_replication_recovery
通道上使用。 - 加密连接。 MySQL Server 自 MySQL 8.0.16 起支持 TLSv1.3 协议,前提是 MySQL 使用了 OpenSSL 1.1.1 或更高版本进行编译。在 MySQL 8.0.16 和 MySQL 8.0.17 中,如果服务器支持 TLSv1.3,则该协议在组通信引擎中不受支持,无法被 Group Replication 使用。从 MySQL 8.0.18 开始,Group Replication 支持 TLSv1.3,可以用于组通信连接和分布式恢复连接。
在 MySQL 8.0.18 中,TLSv1.3 可以用于 Group Replication 的分布式恢复连接,但group_replication_recovery_tls_version
和group_replication_recovery_tls_ciphersuites
系统变量不可用。因此,捐赠服务器必须允许使用至少一个默认启用的 TLSv1.3 密码套件,如第 8.3.2 节“加密连接 TLS 协议和密码套件”中列出的那样。从 MySQL 8.0.19 开始,您可以使用选项配置客户端支持任意选择的密码套件,包括仅使用非默认密码套件。 - 克隆操作。 Group Replication 启动并管理用于分布式恢复的克隆操作,但已设置为支持克隆的组成员也可以参与用户手动启动的克隆操作。在 MySQL 8.0.20 之前的版本中,如果操作涉及正在运行 Group Replication 的组成员,则无法手动启动克隆操作。从 MySQL 8.0.20 开始,只要克隆操作不会删除并替换接收方的数据,就可以执行此操作。因此,如果 Group Replication 正在运行,则启动克隆操作的语句必须包含
DATA DIRECTORY
子句。请参阅 Section 20.5.4.2.4, “Cloning for Other Purposes”。
组大小限制
单个复制组中可以成为成员的 MySQL 服务器的最大数量为 9。如果更多成员尝试加入组,则其请求将被拒绝。这个限制是通过测试和基准测试确定的,作为组在稳定的局域网上可靠运行的安全边界。
事务大小限制
如果单个事务导致消息内容过大,以至于在 5 秒窗口内无法在组成员之间复制消息,那么成员可能会被怀疑失败,然后被驱逐,仅仅因为它们正忙于处理事务。大型事务也可能导致系统由于内存分配问题而变慢。为避免这些问题,请使用以下缓解措施:
- 如果由于大型消息而发生不必要的驱逐,请使用系统变量
group_replication_member_expel_timeout
在怀疑失败的成员被驱逐之前提供额外的时间。在初始的 5 秒检测期之后,您可以允许多达一小时的时间,然后才将怀疑的成员从组中驱逐。从 MySQL 8.0.21 开始,默认情况下额外允许 5 秒。 - 在可能的情况下,在交由 Group Replication 处理之前,尽量限制事务的大小。例如,将与
LOAD DATA
一起使用的文件拆分为较小的块。 - 使用系统变量
group_replication_transaction_size_limit
来指定组接受的最大事务大小。在 MySQL 8.0 中,此系统变量默认为最大事务大小为 150000000 字节(约 143 MB)。超过此大小的事务将被回滚,并且不会发送到 Group Replication 的 Group Communication System (GCS)以分发给组。根据您需要组容忍的最大消息大小调整此变量的值,要牢记处理事务所需的时间与其大小成正比。 - 使用系统变量
group_replication_compression_threshold
来指定应用压缩的消息大小阈值。该系统变量默认为 1000000 字节(1 MB),因此大消息会自动进行压缩。当 Group Replication 的 Group Communication System(GCS)接收到一个由group_replication_transaction_size_limit
设置允许但超过group_replication_compression_threshold
设置的消息时,将执行压缩。更多信息,请参见第 20.7.4 节,“消息压缩”。 - 使用系统变量
group_replication_communication_max_message_size
来指定应用分段的消息大小阈值。该系统变量默认为 10485760 字节(10 MiB),因此大消息会自动进行分段。如果压缩后的消息仍超过group_replication_communication_max_message_size
限制,GCS 将在压缩后执行分段。为了使复制组使用分段,所有组成员必须使用 MySQL 8.0.16 或更高版本,并且组使用的 Group Replication 通信协议版本必须允许分段。更多信息,请参见第 20.7.5 节,“消息分段”。
最大交易大小、消息压缩和消息分段都可以通过指定相关系统变量的零值来停用。如果您已停用了所有这些保护措施,那么在复制组成员的应用程序线程可以处理的消息的上限大小是成员的replica_max_allowed_packet
或slave_max_allowed_packet
系统变量的值,这些变量的默认和最大值为 1073741824 字节(1 GB)。当接收成员尝试处理超过此限制的消息时,消息将失败。组成员可以发起并尝试传输到组的消息的上限大小为 4294967295 字节(约 4 GB)。这是接受由组复制(XCom,一种 Paxos 变体)的组通信引擎处理后的消息的数据包大小的硬限制,GCS 在处理消息后接收它们。当发起成员尝试广播超过此限制的消息时,消息将失败。
MySQL8 中文参考(八十一)(3)https://developer.aliyun.com/article/1566074