MySQL8-中文参考-三十四-

MySQL8 中文参考(三十四)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

原文:dev.mysql.com/doc/refman/8.0/en/myisam-table-close.html

18.2.4.2 未正确关闭表导致的问题

每个MyISAM索引文件(.MYI文件)的头部都有一个计数器,可用于检查表是否已正确关闭。如果您从CHECK TABLEmyisamchk收到以下警告,则表示该计数器已经不同步:

clients are using or haven't closed the table properly

此警告并不一定意味着表已损坏,但您至少应该检查表。

该计数器的工作方式如下:

  • 在 MySQL 中第一次更新表时,索引文件头部的计数器会递增。

  • 在进一步更新期间,计数器不会更改。

  • 当表的最后一个实例关闭时(因为执行了FLUSH TABLES操作或因为表缓存中没有空间),如果表在任何时候已更新,则计数器会递减。

  • 当修复表或检查表并发现表正常时,计数器将被重置为零。

  • 为避免与可能检查表的其他进程交互的问题,如果计数器为零,则在关闭时不会减少。

换句话说,只有在以下情况下计数器才会变得不正确:

  • 一个MyISAM表在未首先执行LOCK TABLESFLUSH TABLES的情况下被复制。

  • MySQL 在更新和最终关闭之间崩溃。(表可能仍然正常,因为 MySQL 总是在每个语句之间为所有内容发出写入。)

  • 一个表在被myisamchk --recovermyisamchk --update-state修改时,同时被mysqld使用。

  • 多个mysqld服务器正在使用该表,其中一个服务器在另一个服务器使用该表时执行了REPAIR TABLECHECK TABLE。在这种设置中,使用CHECK TABLE是安全的,尽管您可能会收到其他服务器的警告。但是,应避免使用REPAIR TABLE,因为当一个服务器用新文件替换数据文件时,其他服务器不知道这一点。

    一般来说,将数据目录共享给多台服务器是一个不好的主意。参见第 7.8 节,“在一台机器上运行多个 MySQL 实例”,进行进一步讨论。

18.3 MEMORY 存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/memory-storage-engine.html

MEMORY 存储引擎(以前称为 HEAP)创建内容存储在内存中的特殊用途表。由于数据容易受到崩溃、硬件问题或停电的影响,只能将这些表用作临时工作区或从其他表中提取数据的只读缓存。

表 18.4 MEMORY 存储引擎特性

特性 支持
B 树索引
备份/时间点恢复(在服务器中实现,而不是在存储引擎中。)
集群数据库支持
聚集索引
压缩数据
数据缓存 不适用
加密数据 是(通过加密函数在服务器中实现。)
外键支持
全文搜索索引
地理空间数据类型支持
地理空间索引支持
哈希索引
索引缓存 不适用
锁定粒度
MVCC
复制支持(在服务器中实现,而不是在存储引擎中。) 有限(请参见本节后面的讨论。)
存储限制 RAM
T 树索引
事务
更新数据字典统计信息
特性 支持
  • 何时使用 MEMORY 或 NDB 集群

  • 分区

  • 性能特性

  • MEMORY 表的特点

  • MEMORY 表的 DDL 操作

  • 索引

  • 用户创建和临时表

  • 加载数据

  • MEMORY 表和复制

  • 管理内存使用

  • 其他资源

何时使用 MEMORY 或 NDB 集群

寻求部署使用 MEMORY 存储引擎处理重要、高可用或频繁更新数据的应用程序的开发人员应考虑 NDB Cluster 是否更合适。MEMORY 引擎的典型用例包括以下特点:

  • 涉及瞬态、非关键数据的操作,如会话管理或缓存。当 MySQL 服务器停止或重新启动时,MEMORY 表中的数据将丢失。

  • 内存存储以实现快速访问和低延迟。数据量完全可以放入内存,而不会导致操作系统交换虚拟内存页。

  • 读取为主或只读数据访问模式(有限更新)。

NDB Cluster 提供与 MEMORY 引擎相同的功能,性能水平更高,并提供 MEMORY 不支持的其他功能:

  • 行级锁定和多线程操作可减少客户端之间的低争用。

  • 即使包含写操作的语句混合,也具有可伸缩性。

  • 可选的磁盘支持操作以实现数据持久性。

  • 无共享架构和无单点故障的多主机操作,实现 99.999%的可用性。

  • 跨节点自动数据分布;应用程序开发人员无需设计自定义分片或分区解决方案。

  • 支持变长数据类型(包括BLOBTEXT),MEMORY 不支持。

分区

MEMORY 表不支持分区。

性能特征

MEMORY 性能受限于单线程执行和处理更新时的表锁定开销所导致的争用。当负载增加时,特别是包含写操作的语句混合时,这限制了可伸缩性。

尽管 MEMORY 表采用内存处理,但在繁忙服务器上,对于通用查询或读写工作负载,它们不一定比InnoDB表更快。特别是,执行更新涉及的表锁定可能会减慢多个会话中对 MEMORY 表的并发使用。

根据在 MEMORY 表上执行的查询类型,您可以创建索引作为默认哈希数据结构(用于基于唯一键查找单个值)或通用的 B 树数据结构(用于涉及等式、不等式或范围运算符(如小于或大于)的所有查询)。以下部分说明了创建这两种索引的语法。一个常见的性能问题是在 B 树索引更有效的工作负载中使用默认哈希索引。

MEMORY 表的特点

MEMORY 存储引擎不在磁盘上创建任何文件。表定义存储在 MySQL 数据字典中。

MEMORY 表具有以下特点:

  • MEMORY 表的空间是以小块分配的。表使用 100% 的动态哈希插入。不需要溢出区域或额外的键空间。不需要额外的空间用于空闲列表。删除的行被放入一个链表中,在你向表中插入新数据时被重用。MEMORY 表也没有通常与哈希表中的删除加插入相关的问题。

  • MEMORY 表使用固定长度的行存储格式。可变长度类型如 VARCHAR 使用固定长度存储。

  • MEMORY 表不能包含 BLOBTEXT 列。

  • MEMORY 包括对 AUTO_INCREMENT 列的支持。

  • 非临时的 MEMORY 表在所有客户端之间共享,就像任何其他非临时表一样。

MEMORY 表的 DDL 操作

要创建一个 MEMORY 表,在 CREATE TABLE 语句中指定 ENGINE=MEMORY 子句。

CREATE TABLE t (i INT) ENGINE = MEMORY;

如引擎名称所示,MEMORY 表存储在内存中。它们默认使用哈希索引,使得单值查找非常快速,并且非常适用于创建临时表。然而,当服务器关闭时,所有存储在 MEMORY 表中的行都会丢失。表本身会继续存在,因为它们的定义存储在 MySQL 数据字典中,但在服务器重新启动时它们是空的。

这个例子展示了如何创建、使用和移除一个 MEMORY 表:

mysql> CREATE TABLE test ENGINE=MEMORY
           SELECT ip,SUM(downloads) AS down
           FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;

MEMORY 表的最大大小受 max_heap_table_size 系统变量限制,默认值为 16MB。要为 MEMORY 表强制不同的大小限制,改变这个变量的值。对于 CREATE TABLE,或随后的 ALTER TABLETRUNCATE TABLE,生效的值将用于表的生命周期。服务器重新启动也会将现有 MEMORY 表的最大大小设置为全局 max_heap_table_size 值。你可��像本节后面描述的那样为单个表设置大小。

索引

MEMORY 存储引擎支持 HASHBTREE 索引。你可以通过添加 USING 子句来指定给定索引使用的其中一个,如下所示:

CREATE TABLE lookup
    (id INT, INDEX USING HASH (id))
    ENGINE = MEMORY;
CREATE TABLE lookup
    (id INT, INDEX USING BTREE (id))
    ENGINE = MEMORY;

关于 B 树和哈希索引的一般特性,请参阅 第 10.3.1 节,“MySQL 如何使用索引”。

MEMORY 表每个表最多可以有 64 个索引,每个索引最多有 16 列,最大键长度为 3072 字节。

如果MEMORY表的哈希索引具有高度的键重复(许多包含相同值的索引条目),那么影响键值的表更新和所有删除操作将显着变慢。这种减速程度与重复程度成正比(或者与索引基数成反比)。您可以使用BTREE索引来避免这个问题。

MEMORY表可以具有非唯一键。(这是哈希索引实现的一个不常见的特性。)

索引的列可以包含NULL值。

用户创建的临时表

MEMORY表内容存储在内存中,这是MEMORY表与服务器在处理查询时动态创建的内部临时表共享的属性。然而,这两种类型的表在以下方面有所不同:MEMORY表不受存储转换的影响,而内部临时表受到影响:

  • 如果内部临时表变得太大,服务器会自动将其转换为磁盘存储,如第 10.4.4 节,“MySQL 中的内部临时表使用”所述。

  • 用户创建的MEMORY表永远不会转换为磁盘表。

加载数据

在 MySQL 服务器启动时填充MEMORY表,您可以使用init_file系统变量。例如,您可以将诸如INSERT INTO ... SELECTLOAD DATA之类的语句放入文件中,从持久数据源加载表,并使用init_file命名文件。请参见第 7.1.8 节,“服务器系统变量”和第 15.2.9 节,“LOAD DATA 语句”。

MEMORY 表和复制

当复制源服务器关闭并重新启动时,其MEMORY表变为空。为了将此效果复制到副本,源在启动后第一次使用给定的MEMORY表时,它会记录一个事件,通知副本必须通过向二进制日志写入该表的DELETE或(从 MySQL 8.0.22 开始)TRUNCATE TABLE语句来清空该表。当副本服务器关闭并重新启动时,其MEMORY表也变为空,并且它会向自己的二进制日志写入一个DELETE或(从 MySQL 8.0.22 开始)TRUNCATE TABLE语句,这些语句会传递给任何下游副本。

当您在复制拓扑中使用MEMORY表时,在某些情况下,源表和副本表可能会有所不同。有关处理这些情况以防止过时读取或错误的信息,请参阅 Section 19.5.1.21,“复制和 MEMORY 表”。

管理内存使用

服务器需要足够的内存来同时维护所有正在使用的MEMORY表。

如果您从MEMORY表中删除单个行,则不会回收内存。只有在删除整个表时才会回收内存。先前用于已删除行的内存将在同一表中为新行重新使用。当您不再需要其内容时,要释放MEMORY表使用的所有内存,请执行DELETETRUNCATE TABLE以删除所有行,或使用DROP TABLE完全删除表。要释放已删除行使用的内存,请使用ALTER TABLE ENGINE=MEMORY强制表重建。

MEMORY表中,一个行所需的内存通过以下表达式计算:

SUM_OVER_ALL_BTREE_KEYS(*max_length_of_key* + sizeof(char*) * 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)
+ ALIGN(*length_of_row*+1, sizeof(char*))

ALIGN()表示一个向上取整的因子,使行长度成为char指针大小的精确倍数。在 32 位机器上,sizeof(char*)为 4,在 64 位机器上为 8。

如前所述,max_heap_table_size系统变量设置了MEMORY表的最大大小限制。要控制各个表的最大大小,需在创建每个表之前设置此变量的会话值。(除非您打算将该值用于所有客户端创建的MEMORY表,否则不要更改全局max_heap_table_size值。)以下示例创建了两个MEMORY表,分别具有 1MB 和 2MB 的最大大小:

mysql> SET max_heap_table_size = 1024*1024;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)

mysql> SET max_heap_table_size = 1024*1024*2;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)

如果服务器重新启动,两个表都会恢复到服务器的全局max_heap_table_size值。

您还可以在CREATE TABLE语句中为MEMORY表指定MAX_ROWS表选项,以提供关于您计划在其中存储的行数的提示。这不会使表增长超过max_heap_table_size值,该值仍然作为最大表大小的约束。为了能够灵活使用MAX_ROWS,请将max_heap_table_size设置至少与您希望每个MEMORY表能够增长的值一样高。

附加资源

一个专门致力于MEMORY存储引擎的论坛可在forums.mysql.com/list.php?92找到。

18.4 CSV 存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/csv-storage-engine.html

18.4.1 修复和检查 CSV 表

18.4.2 CSV 限制

CSV存储引擎使用逗号分隔值格式将数据存储在文本文件中。

CSV存储引擎始终编译到 MySQL 服务器中。

要查看CSV引擎的源代码,请查看 MySQL 源代码分发中的storage/csv目录。

当你创建一个CSV表时,服务器会创建一个以表名开头并以.CSV扩展名结尾的纯文本数据文件。当你将数据存储到表中时,存储引擎会将其保存为逗号分隔值格式的数据文件。

mysql> CREATE TABLE test (i INT NOT NULL, c CHAR(10) NOT NULL)
       ENGINE = CSV;
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO test VALUES(1,'record one'),(2,'record two');
Query OK, 2 rows affected (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test;
+---+------------+
| i | c          |
+---+------------+
| 1 | record one |
| 2 | record two |
+---+------------+
2 rows in set (0.00 sec)

创建一个CSV表还会创建一个相应的元文件,用于存储表的状态和表中存在的行数。该文件的名称与表名相同,扩展名为CSM

如果你检查执行上述语句创建的数据库目录中的test.CSV文件,其内容应该如下所示:

"1","record one"
"2","record two"

这种格式可以被电子表格应用程序(如 Microsoft Excel)读取,甚至写入。

18.4.1 修复和检查 CSV 表格

原文:dev.mysql.com/doc/refman/8.0/en/se-csv-repair.html

CSV存储引擎支持CHECK TABLEREPAIR TABLE语句,用于验证并且在可能的情况下修复损坏的CSV表格。

运行CHECK TABLE语句时,会通过查找正确的字段分隔符、转义字段(匹配或缺失的引号)、与表定义相比的正确字段数量以及相应的CSV元文件的存在来检查CSV文件的有效性。发现的第一个无效行会导致错误。检查一个有效的表格会产生类似于以下所示的输出:

mysql> CHECK TABLE csvtest;
+--------------+-------+----------+----------+
| Table        | Op    | Msg_type | Msg_text |
+--------------+-------+----------+----------+
| test.csvtest | check | status   | OK       |
+--------------+-------+----------+----------+

对于损坏的表格进行检查会返回诸如以下的错误:

mysql> CHECK TABLE csvtest;
+--------------+-------+----------+----------+
| Table        | Op    | Msg_type | Msg_text |
+--------------+-------+----------+----------+
| test.csvtest | check | error    | Corrupt  |
+--------------+-------+----------+----------+

要修复表格,请使用REPAIR TABLE语句,它会尽可能从现有的CSV数据中复制尽可能多的有效行,然后用恢复的行替换现有的CSV文件。任何在损坏数据之后的行都会丢失。

mysql> REPAIR TABLE csvtest;
+--------------+--------+----------+----------+
| Table        | Op     | Msg_type | Msg_text |
+--------------+--------+----------+----------+
| test.csvtest | repair | status   | OK       |
+--------------+--------+----------+----------+

警告

在修复过程中,只有从CSV文件中第一个损坏行之前的行会被复制到新表中。从第一个损坏行到表格末尾的所有其他行都会被移除,即使是有效行也会被移除。

18.4.2 CSV 限制

原文:dev.mysql.com/doc/refman/8.0/en/se-csv-limitations.html

CSV存储引擎不支持索引。

CSV存储引擎不支持分区。

使用CSV存储引擎创建的所有表必须在所有列上具有NOT NULL属性。

18.5 ARCHIVE 存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/archive-storage-engine.html

ARCHIVE 存储引擎生成专用表,以非常小的占用空间存储大量未索引的数据。

表 18.5 ARCHIVE 存储引擎特性

功能 支持
B-树索引
备份/时间点恢复(在服务器中实现,而不是在存储引擎中。)
集群数据库支持
集群索引
压缩数据
数据缓存
加密数据 是(通过加密函数在服务器中实现。)
外键支持
全文搜索索引
地理空间数据类型支持
地理空间索引支持
哈希索引
索引缓存
锁定粒度
MVCC
复制支持(在服务器中实现,而不是在存储引擎中。)
存储限制
T-树索引
事务
数据字典的更新统计信息
功能 支持

ARCHIVE 存储引擎包含在 MySQL 二进制发行版中。如果您从源代码构建 MySQL,可以通过使用 -DWITH_ARCHIVE_STORAGE_ENGINE 选项在 CMake 中启用此存储引擎。

要查看 ARCHIVE 引擎的源代码,请查看 MySQL 源代码分发中的 storage/archive 目录。

您可以使用 SHOW ENGINES 语句检查 ARCHIVE 存储引擎是否可用。

创建 ARCHIVE 表时,存储引擎会创建以表名开头的文件。数据文件的扩展名为 .ARZ。在优化操作期间可能会出现 .ARN 文件。

ARCHIVE 引擎支持 INSERT, REPLACE, 和 SELECT,但不支持 DELETEUPDATE。它支持 ORDER BY 操作,BLOB 列,以及空间数据类型(参见 第 13.4.1 节,“空间数据类型”)。不支持地理空间参考系统。ARCHIVE 引擎使用行级锁定。

ARCHIVE 引擎支持 AUTO_INCREMENT 列属性。AUTO_INCREMENT 列可以有唯一或非唯一索引。在任何其他列上创建索引会导致错误。ARCHIVE 引擎还支持 CREATE TABLE 语句中的 AUTO_INCREMENT 表选项,用于指定新表的初始序列值或重置现有表的序列值。

ARCHIVE 不支持将值插入到小于当前最大列值的 AUTO_INCREMENT 列中。尝试这样做会导致 ER_DUP_KEY 错误。

如果未请求,ARCHIVE 引擎会忽略 BLOB 列,并在读取时跳过它们。

ARCHIVE 存储引擎不支持分区。

存储: 行在插入时会被压缩。ARCHIVE 引擎使用 zlib 无损数据压缩(参见 www.zlib.net/)。您可以使用 OPTIMIZE TABLE 来分析表并将其打包成更小的格式(关于使用 OPTIMIZE TABLE 的原因,请参见本节后面)。该引擎还支持 CHECK TABLE。有几种类型的插入操作被使用:

  • INSERT 语句只是将行推送到压缩缓冲区中,并在必要时刷新该缓冲区。对缓冲区的插入受到锁的保护。SELECT 强制刷新发生。

  • 仅在批量插入完成后才能看到,除非同时发生其他插入操作,此时可能部分可见。SELECT 永远不会导致批量插入的刷新,除非在加载时发生正常插入。

检索:在检索时,行会按需解压缩;没有行缓存。SELECT 操作执行完整的表扫描:当发生 SELECT 时,它会找出当前有多少行并读取这些行。SELECT 作为一致性读取执行。请注意,插入期间大量的 SELECT 语句可能会降低压缩效果,除非只使用批量插入。为了获得更好的压缩效果,您可以使用 OPTIMIZE TABLEREPAIR TABLESHOW TABLE STATUS 报告的 ARCHIVE 表中的行数始终是准确的。请参阅 Section 15.7.3.4, “OPTIMIZE TABLE Statement”,Section 15.7.3.5, “REPAIR TABLE Statement” 和 Section 15.7.7.38, “SHOW TABLE STATUS Statement”。

其他资源

18.6 BLACKHOLE 存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/blackhole-storage-engine.html

BLACKHOLE存储引擎充当一个“黑洞”,接受数据但将其丢弃并不存储。检索总是返回空结果:

mysql> CREATE TABLE test(i INT, c CHAR(10)) ENGINE = BLACKHOLE;
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO test VALUES(1,'record one'),(2,'record two');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test;
Empty set (0.00 sec)

如果您从源代码构建 MySQL 并希望启用BLACKHOLE存储引擎,请使用-DWITH_BLACKHOLE_STORAGE_ENGINE选项调用CMake

要查看BLACKHOLE引擎的源代码,请查看 MySQL 源代码分发的sql目录。

当您创建一个BLACKHOLE表时,服务器会在全局数据字典中创建表定义。与表相关联的文件不存在。

BLACKHOLE存储引擎支持各种类型的索引。也就是说,您可以在表定义中包含索引声明。

截至 MySQL 8.0.27,最大键长度为 3072 字节。在 8.0.27 之前,最大键长度为 1000 字节。

BLACKHOLE存储引擎不支持分区。

您可以使用SHOW ENGINES语句检查BLACKHOLE存储引擎是否可用。

插入到BLACKHOLE表中不会存储任何数据,但如果启用基于语句的二进制日志记录,则会记录 SQL 语句并复制到副本服务器。这可以作为中继器或过滤器机制。

假设您的应用程序需要副本端过滤规则,但首先将所有二进制日志数据传输到副本会导致太多的流量。在这种情况下,可以在复制源服务器上设置一个默认存储引擎为BLACKHOLE的“虚拟”副本进程,如下所示:

图 18.1 使用 BLACKHOLE 进行过滤的复制

复制源服务器使用源 mysqld 进程和虚拟 mysqld 进程。在副本中,mysqld 进程从虚拟 mysqld 进程复制。

源服务器写入其二进制日志。“虚拟”mysqld进程充当副本,应用所需的replicate-do-*replicate-ignore-*规则,并写入自己的新的、经过过滤的二进制日志。(参见 Section 19.1.6, “Replication and Binary Logging Options and Variables”.)这个经过过滤的日志提供给副本。

虚拟进程实际上不存储任何数据,因此在复制源服务器上运行额外的mysqld进程几乎没有处理开销。可以通过额外的副本重复这种设置。

BLACKHOLE 表的 INSERT 触发器按预期工作。但是,由于 BLACKHOLE 表实际上不存储任何数据,因此不会激活 UPDATEDELETE 触发器:触发器定义中的 FOR EACH ROW 子句不适用,因为没有行。

BLACKHOLE 存储引擎的其他可能用途包括:

  • 验证转储文件语法。

  • 通过比较启用和禁用二进制日志记录时使用 BLACKHOLE 的性能来测量二进制日志记录的开销。

  • BLACKHOLE 本质上是一个“无操作”存储引擎,因此可以用于查找与存储引擎本身无关的性能瓶颈。

BLACKHOLE 引擎是事务感知的,即已提交的事务会被写入二进制日志,而回滚的事务则不会。

黑洞引擎和自增列

BLACKHOLE 引擎是一个无操作引擎。对使用 BLACKHOLE 的表执行的任何操作都没有效果。在考虑自增主键列的行为时,应牢记这一点。该引擎不会自动增加字段值,并且不会保留自增字段状态。这在复制中具有重要影响。

考虑以下复制场景,其中所有以下三个条件都适用:

  1. 在源服务器上有一个带有自增字段的黑洞表,该字段是主键。

  2. 在副本中存在相同的表,但使用 MyISAM 引擎。

  3. INSERT 语句本身中或通过使用 SET INSERT_ID 语句显式设置自增值,将数据插入源表。

在这种情况下,复制会因主键列上的重复条目错误而失败。

在基于语句的复制中,上下文事件中的 INSERT_ID 值始终相同。因此,由于尝试插入具有主键列重复值的行,复制失败。

在基于行的复制中,引擎为每次插入返回的行值始终相同。这导致副本尝试使用相同值为主键列重放两个插入日志条目,因此复制失败。

列过滤

当使用基于行的复制(binlog_format=ROW)时,支持表中缺少最后列的副本,如第 19.5.1.9 节,“源和副本上具有不同表定义的复制”中所述。

此过滤在副本端执行,即在过滤之前将列复制到副本。至少有两种情况下不希望将列复制到副本:

  1. 如果数据是机密的,那么副本服务器不应该访问它。

  2. 如果源有很多副本,那么在发送到副本之前进行过滤可能会减少网络流量。

使用BLACKHOLE引擎可以实现源列过滤。这是通过类似于源表过滤的方式实现的 - 使用BLACKHOLE引擎和--replicate-do-table--replicate-ignore-table选项。

源的设置为:

CREATE TABLE t1 (public_col_1, ..., public_col_N,
                 secret_col_1, ..., secret_col_M) ENGINE=MyISAM;

受信任副本的设置为:

CREATE TABLE t1 (public_col_1, ..., public_col_N) ENGINE=BLACKHOLE;

不受信任副本的设置为:

CREATE TABLE t1 (public_col_1, ..., public_col_N) ENGINE=MyISAM;

18.7 MERGE 存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/merge-storage-engine.html

18.7.1 MERGE 表优缺点

18.7.2 MERGE 表问题

MERGE存储引擎,也称为MRG_MyISAM引擎,是一组相同的MyISAM表,可以作为一个使用。“相同”意味着所有表具有相同的列数据类型和索引信息。您不能合并列在不同顺序中列出、相应列中的数据类型不完全相同或索引顺序不同的MyISAM表。但是,任何或所有MyISAM表都可以使用myisampack进行压缩。请参见第 6.6.6 节,“myisampack — 生成压缩的只读 MyISAM 表”。这些表之间的差异并不重要:

  • 相应列和索引的名称可能不同。

  • 表、列和索引的注释可能不同。

  • 表选项如AVG_ROW_LENGTHMAX_ROWSPACK_KEYS可能不同。

MERGE表的替代方案是分区表,它将单个表的分区存储在单独的文件中,并使某些操作更有效。有关更多信息,请参见第二十六章,分区

创建MERGE表时,MySQL 在磁盘上创建一个包含应作为一个的底层MyISAM表名称的.MRG文件。MERGE表的表格式存储在 MySQL 数据字典中。底层表不必与MERGE表在同一个数据库中。

您可以在MERGE表上使用SELECTDELETEUPDATEINSERT。您必须对映射到MERGE表的MyISAM表具有SELECTDELETEUPDATE权限。

注意

使用MERGE表会带来以下安全问题:如果用户可以访问MyISAMt,那么该用户可以创建一个访问tMERGEm。然而,如果用户对t的权限随后被撤销,用户仍然可以通过m继续访问t

使用DROP TABLEMERGE表仅删除MERGE规范。底层表不受影响。

要创建MERGE表,必须指定一个UNION=(*table 列表*)选项,指示要使用哪些MyISAM表。您还可以选择指定INSERT_METHOD选项来控制插入到MERGE表的方式。使用FIRSTLAST的值会导致插入到第一个或最后一个底层表中。如果不指定INSERT_METHOD选项或指定为NO,则不允许向MERGE表插入数据,尝试这样做会导致错误。

以下示例展示了如何创建MERGE表:

mysql> CREATE TABLE t1 (
 ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 ->    message CHAR(20)) ENGINE=MyISAM;
mysql> CREATE TABLE t2 (
 ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 ->    message CHAR(20)) ENGINE=MyISAM;
mysql> INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
mysql> INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
mysql> CREATE TABLE total (
 ->    a INT NOT NULL AUTO_INCREMENT,
 ->    message CHAR(20), INDEX(a))
 ->    ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

a在底层MyISAM表中作为PRIMARY KEY进行索引,但在MERGE表中不是。在那里进行了索引,但不是作为PRIMARY KEY,因为MERGE表无法强制底层表的唯一性。(类似地,在底层表中具有UNIQUE索引的列应该在MERGE表中进行索引,但不作为UNIQUE索引。)

创建MERGE表后,可以使用它来发出对整个表组的查询:

mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table   |
| 3 | t1      |
| 1 | Testing |
| 2 | table   |
| 3 | t2      |
+---+---------+

要将MERGE表重新映射到不同的MyISAM表集合,可以使用以下方法之一:

  • DROPMERGE表并重新创建它。

  • 使用ALTER TABLE *tbl_name* UNION=(...)来更改底层表的列表。

    也可以使用ALTER TABLE ... UNION=()(即,使用空的UNION子句)来移除所有底层表。然而,在这种情况下,表实际上是空的,插入操作会失败,因为没有底层表来接收新行。这样的表可能用作创建新MERGE表的模板,使用CREATE TABLE ... LIKE

底层表的定义和索引必须与MERGE表的定义密切符合。符合性是在打开作为MERGE表一部分的表时进行检查的,而不是在创建MERGE表时进行检查的。如果任何表未通过符合性检查,触发打开表的操作将失败。这意味着更改MERGE中表的定义可能会导致在访问MERGE表时失败。应用于每个表的符合性检查包括:

  • 底层表和MERGE表必须具有相同数量的列。

  • 底层表和MERGE表中的列顺序必须匹配。

  • 此外,父MERGE表和底层表中每个对应列的规范都会进行比较,并且必须满足这些检查:

    • 底层表和MERGE表中的列类型必须相等。

    • 底层表和MERGE表中的列长度必须相等。

    • 底层表和MERGE表中的列可以是NULL

  • 基础表必须至少有与MERGE表相同数量的索引。基础表可能比MERGE表拥有更多索引,但不能少于MERGE表。

    注意

    已知存在一个问题,即相同列上的索引在MERGE表和基础MyISAM表中必须按相同顺序排列。请参阅 Bug #33653。

    每个索引必须满足这些检查:

    • 基础表和MERGE表的索引类型必须相同。

    • 索引定义中的索引部分数量(即,在复合索引内的多个列)必须相同,对应基础表和MERGE表。

    • 对于每个索引部分:

      • 索引部分长度必须相等。

      • 索引部分类型必须相等。

      • 索引部分语言必须相等。

      • 检查索引部分是否可以为NULL

如果由于基础表的问题而无法打开或使用MERGE表,则CHECK TABLE会显示导致问题的表的信息。

其他资源

18.7.1 MERGE 表的优缺点

原文:dev.mysql.com/doc/refman/8.0/en/merge-table-advantages.html

MERGE表可以帮助你解决以下问题:

  • 轻松管理一组日志表。例如,你可以将不同月份的数据放入单独的表中,压缩其中一些表,并创建一个MERGE表将它们作为一个整体使用。

  • 获得更快的速度。你可以根据某些标准将一个大的只读表拆分,并将单独的表放在不同的磁盘上。以这种方式结构化的MERGE表可能比使用单个大表要快得多。

  • 执行更有效的搜索。如果你确切知道你要找的内容,你可以仅在底层表中搜索某些查询,并对其他查询使用MERGE表。你甚至可以有许多使用重叠表集的不同MERGE表。

  • 执行更有效的修复。修复映射到MERGE表的个别较小表比修复单个大表更容易。

  • 瞬间将多个表映射为一个。MERGE表不需要维护自己的索引,因为它使用各个表的索引。因此,MERGE表集合创建或重新映射非常快速。(当创建MERGE表时,仍然必须指定索引定义,即使不创建索引。)

  • 如果你有一组表,可以根据需要创建一个大表,那么你可以根据需要从中创建一个MERGE表。这样做会快得多,并节省大量磁盘空间。

  • 超出操作系统的文件大小限制。每个MyISAM表受此限制约束,但MyISAM表的集合不受限制。

  • 你可以通过定义一个映射到单个表的MERGE表来为MyISAM表创建别名或同义词。这样做几乎没有什么明显的性能影响(每次读取只有几个间接调用和memcpy()调用)。

MERGE表的缺点包括:

  • 你只能使用相同的MyISAM表来创建MERGE表。

  • MERGE表中无法使用一些MyISAM功能。例如,你不能在MERGE表上创建FULLTEXT索引。(你可以在底层的MyISAM表上创建FULLTEXT索引,但不能使用全文搜索搜索MERGE表。)

  • 如果MERGE表是非临时的,则所有底层的MyISAM表必须是非临时的。如果MERGE表是临时的,则MyISAM表可以是任意混合的临时和非临时。

  • MERGE表比MyISAM表使用更多的文件描述符。如果有 10 个客户端使用映射到 10 个表的MERGE表,则服务器使用(10 × 10)+ 10 个文件描述符。(每个客户端的 10 个数据文件描述符,以及在客户端之间共享的 10 个索引文件描述符。)

  • 索引读取速度较慢。当你读取一个索引时,MERGE 存储引擎需要在所有底层表上发出读取操作,以检查哪个最接近给定索引值。要读取下一个索引值,MERGE 存储引擎需要搜索读取缓冲区以找到下一个值。只有当一个索引缓冲区被用完时,存储引擎才需要读取下一个索引块。这使得 MERGE 索引在 eq_ref 搜索上要慢得多,但在 ref 搜索上并不慢。有关 eq_refref 的更多信息,请参见 第 15.8.2 节,“EXPLAIN 语句”。

18.7.2 MERGE 表问题

原文:dev.mysql.com/doc/refman/8.0/en/merge-table-problems.html

以下是 MERGE 表的已知问题:

  • 在 MySQL Server 版本 5.1.23 之前的版本中,可以创建具有非临时子 MyISAM 表的临时合并表。

    从版本 5.1.23 开始,MERGE 子表通过父表进行锁定。如果父表是临时表,则不会被锁定,因此子表也不会被锁定。同时使用 MyISAM 表会导致数据损坏。

  • 如果使用 ALTER TABLEMERGE 表更改为另一个存储引擎,那么与基础表的映射将丢失。相反,来自基础 MyISAM 表的行将被复制到更改后的表中,然后使用指定的存储引擎。

  • MERGE 表的 INSERT_METHOD 表选项指示要用于向 MERGE 表插入的基础 MyISAM 表。然而,在至少有一行直接插入到 MyISAM 表之前,对该 MyISAM 表使用 AUTO_INCREMENT 表选项对向 MERGE 表的插入没有影响。

  • MERGE 表无法在整个表上维护唯一性约束。当执行 INSERT 时,数据会进入第一个或最后一个 MyISAM 表(由 INSERT_METHOD 选项确定)。MySQL 确保唯一键值在该 MyISAM 表内保持唯一,但不跨所有基础表。

  • 因为 MERGE 引擎无法强制执行基础表集合上的唯一性,REPLACE 无法按预期工作。两个关键事实是:

    • REPLACE 只能检测即将写入的基础表中的唯一键冲突(由 INSERT_METHOD 选项确定)。这与 MERGE 表本身中的冲突不同。

    • 如果 REPLACE 检测到唯一键冲突,它只会更改正在写入的基础表中的相应行;也就是说,由 INSERT_METHOD 选项确定的第一个或最后一个表。

    对于 INSERT ... ON DUPLICATE KEY UPDATE,类似的考虑也适用。

  • MERGE 表不支持分区。也就是说,无法对 MERGE 表进行分区,MERGE 表的任何基础 MyISAM 表也无法进行分区。

  • 不应在任何映射到打开 MERGE 表中的表上使用 ANALYZE TABLEREPAIR TABLEOPTIMIZE TABLEALTER TABLEDROP TABLE、不带 WHERE 子句的 DELETETRUNCATE TABLE。如果这样做,MERGE 表可能仍然引用原始表并产生意外结果。为了解决这个问题,在执行任何命名操作之前,确保没有任何 MERGE 表保持打开状态,通过发出一个 FLUSH TABLES 语句。

    意外结果包括 MERGE 表上的操作可能报告表损坏的可能性。如果在底层 MyISAM 表的命名操作之后发生这种情况,则损坏消息是虚假的。为了解决这个问题,在修改 MyISAM 表后,发出一个 FLUSH TABLES 语句。

  • 在 Windows 上,对正在被 MERGE 表使用的表执行 DROP TABLE 操作是无效的,因为 MySQL 的 MERGE 存储引擎的表映射对于上层是隐藏的。Windows 不允许删除打开的文件,因此在删除表之前,你必须先刷新所有的 MERGE 表(使用 FLUSH TABLES)或者删除 MERGE 表。

  • 当访问表时(例如,作为 SELECTINSERT 语句的一部分),MyISAM 表和 MERGE 表的定义会被检查。这些检查通过比较列顺序、类型、大小和相关索引来确保表的定义和父 MERGE 表的定义匹配。如果表之间存在差异,将返回错误并导致语句失败。由于这些检查发生在表被打开时,对单个表的定义进行任何更改,包括列更改、列排序和引擎更改都会导致语句失败。

  • MERGE 表及其基础表中索引的顺序应该相同。如果使用 ALTER TABLE 在用于 MERGE 表的表上添加一个 UNIQUE 索引,然后再在 MERGE 表上添加一个非唯一索引,如果基础表中已经有一个非唯一索引,那么这些表的索引顺序就会不同。 (这是因为 ALTER TABLEUNIQUE 索引放在非唯一索引之前,以便快速检测重复键。) 因此,对具有这些索引的表的查询可能会返回意外结果。

  • 如果遇到类似于 ERROR 1017 (HY000): Can't find file: 'tbl_name.MRG' (errno: 2) 的错误消息,通常表示一些基础表没有使用 MyISAM 存储引擎。确认所有这些表都是 MyISAM

  • MERGE 表中的最大行数为 2⁶⁴ (~1.844E+19; 与 MyISAM 表相同)。无法将多个 MyISAM 表合并为一个行数超过此数量的 MERGE 表。

  • 目前已知,使用具有不同行格式的基础 MyISAM 表与父 MERGE 表会失败。请参见 Bug #32364。

  • LOCK TABLES 生效时,您无法更改非临时 MERGE 表的联合列表。以下操作起作用:

    CREATE TABLE m1 ... ENGINE=MRG_MYISAM ...;
    LOCK TABLES t1 WRITE, t2 WRITE, m1 WRITE;
    ALTER TABLE m1 ... UNION=(t1,t2) ...;
    

    但是,您可以使用临时 MERGE 表来实现这一点。

  • 无法使用 CREATE ... SELECT 创建临时 MERGE 表或非临时 MERGE 表。例如:

    CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...;
    

    尝试这样做会导致错误:tbl_name 不是 BASE TABLE

  • 在某些情况下,MERGE 表和基础表之间的 PACK_KEYS 表选项值不同会导致意外结果,如果基础表包含 CHARBINARY 列。作为解决方法,使用 ALTER TABLE 确保所有涉及的表具有相同的 PACK_KEYS 值。 (Bug #50646)

18.8 FEDERATED 存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/federated-storage-engine.html

18.8.1 FEDERATED 存储引擎概述

18.8.2 如何创建 FEDERATED 表

18.8.3 FEDERATED 存储引擎注意事项和提示

18.8.4 FEDERATED 存储引擎资源

FEDERATED存储引擎允许您访问远程 MySQL 数据库中的数据,而无需使用复制或集群技术。查询本地FEDERATED表会自动从远程(联合)表中提取数据。本地表上不存储任何数据。

如果从源代码构建 MySQL 并包含FEDERATED存储引擎,请使用-DWITH_FEDERATED_STORAGE_ENGINE选项调用CMake

运行服务器默认未启用FEDERATED存储引擎;要启用FEDERATED,必须使用--federated选项启动 MySQL 服务器二进制文件。

要查看FEDERATED引擎的源代码,请查看 MySQL 源代码分发中的storage/federated目录。

18.8.1 FEDERATED 存储引擎概述

原文:dev.mysql.com/doc/refman/8.0/en/federated-description.html

当您使用标准存储引擎(如MyISAMCSVInnoDB)之一创建表时,表由表定义和相关数据组成。创建FEDERATED表时,表定义相同,但数据的物理存储在远程服务器上处理。

FEDERATED表由两个元素组成:

  • 具有数据库表的远程服务器,该表又由表定义(存储在 MySQL 数据字典中)和相关表组成。远程表的表类型可以是远程mysqld服务器支持的任何类型,包括MyISAMInnoDB

  • 本地服务器具有一个数据库表,其中表定义与远程服务器上相应表的定义相匹配。表定义存储在数据字典中。本地服务器上没有数据文件。相反,表定义包括一个指向远程表的连接字符串。

在本地服务器上对FEDERATED表执行查询和语句时,通常会向本地数据文件插入、更新或删除信息的操作会被发送到远程服务器进行执行,其中它们会更新远程服务器上的数据文件或从远程服务器返回匹配的行。

FEDERATED表设置的基本结构如图 18.2,“FEDERATED 表结构”所示。

图 18.2 FEDERATED 表结构

内容在周围的文本中描述。

当客户端发出引用FEDERATED表的 SQL 语句时,在本地服务器(执行 SQL 语句的地方)和远程服务器(存储数据的地方)之间的信息流如下:

  1. 存储引擎遍历FEDERATED表具有的每一列,并构造一个适当的 SQL 语句,引用远程表。

  2. 该语句使用 MySQL 客户端 API 发送到远程服务器。

  3. 远程服务器处理语句,本地服务器检索语句产生的任何结果(受影响行数或结果集)。

  4. 如果语句产生结果集,则将每列转换为FEDERATED引擎期望的内部存储引擎格式,并可以将结果显示给发出原始语句的客户端。

本地服务器使用 MySQL 客户端 C API 函数与远程服务器通信。它调用mysql_real_query()来发送语句。要读取结果集,它使用mysql_store_result()并使用mysql_fetch_row()逐行获取行。

18.8.2 如何创建 FEDERATED 表

原文:dev.mysql.com/doc/refman/8.0/en/federated-create.html

18.8.2.1 使用 CONNECTION 创建 FEDERATED 表

18.8.2.2 使用 CREATE SERVER 创建 FEDERATED 表

要创建一个FEDERATED表,您应该按照以下步骤进行:

  1. 在远程服务器上创建表。或者,记录现有表的表定义,可能使用SHOW CREATE TABLE语句。

  2. 在本地服务器上创建一个具有相同表定义的表,但添加连接信息,将本地表与远程表链接起来。

例如,您可以在远程服务器上创建以下表:

CREATE TABLE test_table (
    id     INT(20) NOT NULL AUTO_INCREMENT,
    name   VARCHAR(32) NOT NULL DEFAULT '',
    other  INT(20) NOT NULL DEFAULT '0',
    PRIMARY KEY  (id),
    INDEX name (name),
    INDEX other_key (other)
)
ENGINE=MyISAM
DEFAULT CHARSET=utf8mb4;

要创建与远程表联合的本地表,有两种可用选项。您可以创建本地表并指定连接字符串(包含服务器名称、登录、密码),用于使用CONNECTION连接到远程表,或者您可以使用之前使用CREATE SERVER语句创建的现有连接。

重要

当您创建本地表时,它必须具有与远程表相同的字段定义。

注意

通过为主机上的表添加索引,可以提高FEDERATED表的性能。优化发生的原因是发送到远程服务器的查询包含WHERE子句的内容,并且被发送到远程服务器并在本地执行。这减少了网络流量,否则会请求整个表从服务器传输到本地进行处理。

原文:dev.mysql.com/doc/refman/8.0/en/federated-create-connection.html

18.8.2.1 使用 CONNECTION 创建一个 FEDERATED 表

要使用第一种方法,你必须在 CREATE TABLE 语句中的引擎类型之后指定 CONNECTION 字符串。例如:

CREATE TABLE federated_table (
    id     INT(20) NOT NULL AUTO_INCREMENT,
    name   VARCHAR(32) NOT NULL DEFAULT '',
    other  INT(20) NOT NULL DEFAULT '0',
    PRIMARY KEY  (id),
    INDEX name (name),
    INDEX other_key (other)
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8mb4
CONNECTION='mysql://fed_user@remote_host:9306/federated/test_table';

注意

CONNECTION 取代了一些早期版本的 MySQL 中使用的 COMMENT

CONNECTION 字符串包含连接到包含数据物理存储的远程服务器的信息。连接字符串指定服务器名称、登录凭据、端口号和数据库/表信息。在这个例子中,远程表位于服务器 remote_host 上,使用端口 9306。名称和端口号应该与你想要用作远程表的远程 MySQL 服务器实例的主机名(或 IP 地址)和端口号匹配。

连接字符串的格式如下:

*scheme*://*user_name*[:*password*]@*host_name*[:*port_num*]/*db_name*/*tbl_name*

其中:

  • scheme: 一个被识别的连接协议。目前只支持 mysql 作为 scheme 的值。

  • user_name: 连接的用户名。这个用户必须在远程服务器上创建,并且必须具有执行所需操作(SELECT, INSERT, UPDATE等)所需的适当权限。

  • password: (可选)user_name 对应的密码。

  • host_name: 远程服务器的主机名或 IP 地址。

  • port_num: (可选)远程服务器的端口号。默认值为 3306。

  • db_name: 持有远程表的数据库名称。

  • tbl_name: 远程表的名称。本地表和远程表的名称不必匹配。

示例连接字符串:

CONNECTION='mysql://username:password@hostname:port/database/tablename'
CONNECTION='mysql://username@hostname/database/tablename'
CONNECTION='mysql://username:password@hostname/database/tablename'

原文:dev.mysql.com/doc/refman/8.0/en/federated-create-server.html

18.8.2.2 使用 CREATE SERVER 创建 FEDERATED 表

如果您在同一服务器上创建多个 FEDERATED 表,或者想简化创建 FEDERATED 表的过程,可以使用 CREATE SERVER 语句来定义服务器连接参数,就像您使用 CONNECTION 字符串一样。

CREATE SERVER 语句的格式为:

CREATE SERVER
*server_name*
FOREIGN DATA WRAPPER *wrapper_name*
OPTIONS (*option* [, *option*] ...)

server_name 在创建新的 FEDERATED 表时用于连接字符串。

例如,要创建与 CONNECTION 字符串相同的服务器连接:

CONNECTION='mysql://fed_user@remote_host:9306/federated/test_table';

您将使用以下语句:

CREATE SERVER fedlink
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'fed_user', HOST 'remote_host', PORT 9306, DATABASE 'federated');

要创建一个使用此连接的 FEDERATED 表,仍然使用 CONNECTION 关键字,但指定您在 CREATE SERVER 语句中使用的名称。

CREATE TABLE test_table (
    id     INT(20) NOT NULL AUTO_INCREMENT,
    name   VARCHAR(32) NOT NULL DEFAULT '',
    other  INT(20) NOT NULL DEFAULT '0',
    PRIMARY KEY  (id),
    INDEX name (name),
    INDEX other_key (other)
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8mb4
CONNECTION='fedlink/test_table';

此示例中的连接名称包含连接名称(fedlink)和要链接到的表名称(test_table),用斜杠分隔。 如果只指定连接名称而没有表名称,则使用本地表的表名称。

有关 CREATE SERVER 的更多信息,请参见 Section 15.1.18, “CREATE SERVER Statement”。

CREATE SERVER 语句接受与 CONNECTION 字符串相同的参数。 CREATE SERVER 语句会更新 mysql.servers 表中的行。 有关连接字符串中参数、CREATE SERVER 语句选项以及 mysql.servers 表中列之间的对应关系,请参考以下表格。 供参考,CONNECTION 字符串的格式如下:

*scheme*://*user_name*[:*password*]@*host_name*[:*port_num*]/*db_name*/*tbl_name*
描述 CONNECTION 字符串 CREATE SERVER 选项 mysql.servers
连接方案 scheme wrapper_name Wrapper
远程用户 user_name USER Username
远程密码 password PASSWORD Password
远程主机 host_name HOST Host
远程端口 port_num PORT Port
远程数据库 db_name DATABASE Db

18.8.3 FEDERATED 存储引擎注意事项和提示

原文:dev.mysql.com/doc/refman/8.0/en/federated-usagenotes.html

在使用FEDERATED存储引擎时,应注意以下几点:

  • FEDERATED表可以被复制到其他副本,但必须确保副本服务器能够使用在CONNECTION字符串(或mysql.servers表中的行)中定义的用户/密码组合连接到远程服务器。

以下项目指示了FEDERATED存储引擎支持和不支持的功能:

  • 远程服务器必须是一个 MySQL 服务器。

  • FEDERATED表指向的远程表在通过FEDERATED表访问之前必须存在。

  • 一个FEDERATED表可以指向另一个表,但必须小心不要创建循环。

  • FEDERATED表不支持通常意义上的索引;因为对表数据的访问是远程处理的,实际上是远程表利用索引。这意味着,对于无法使用任何索引并因此需要完整表扫描的查询,服务器会从远程表中获取所有行并在本地进行过滤。这将发生无论此SELECT语句中使用的任何WHERELIMIT;这些子句在本地应用于返回的行。

    未能使用索引的查询可能导致性能不佳和网络负载过重。此外,由于返回的行必须存储在内存中,这样的查询也可能导致本地服务器交换,甚至挂起。

  • 在创建FEDERATED表时应当小心,因为来自等效MyISAM或其他表的索引定义可能不被支持。例如,如果表在任何VARCHARTEXTBLOB列上使用索引前缀,则创建FEDERATED表将失败。以下使用MyISAM的定义是有效的:

    CREATE TABLE `T1`(`A` VARCHAR(100),UNIQUE KEY(`A`(30))) ENGINE=MYISAM;
    

    此示例中的键前缀与FEDERATED引擎不兼容,等效语句将失败:

    CREATE TABLE `T1`(`A` VARCHAR(100),UNIQUE KEY(`A`(30))) ENGINE=FEDERATED
      CONNECTION='MYSQL://127.0.0.1:3306/TEST/T1';
    

    如果可能的话,在远程服务器和本地服务器创建表时,应尽量分开列和索引定义,以避免这些索引问题。

  • 在内部,实现使用SELECTINSERTUPDATEDELETE,但不使用HANDLER

  • FEDERATED存储引擎支持SELECTINSERTUPDATEDELETETRUNCATE TABLE和索引。它不支持ALTER TABLE或任何直接影响表结构的数据定义语言语句,除了DROP TABLE。当前的实现不使用预处理语句。

  • FEDERATED接受INSERT ... ON DUPLICATE KEY UPDATE语句,但如果发生重复键违规,该语句将失败并显示错误。

  • 不支持事务。

  • FEDERATED执行批量插入处理,使多行以批量方式发送到远程表,从而提高性能。此外,如果远程表是事务性的,它可以使远程存储引擎在发生错误时正确执行语句回滚。此功能具有以下限制:

    • 插入的大小不能超过服务器之间的最大数据包大小。如果插入超过此大小,它将被分成多个数据包,可能会出现回滚问题。

    • 不会对INSERT ... ON DUPLICATE KEY UPDATE进行批量插入处理。

  • FEDERATED引擎无法知道远程表是否发生了更改。原因是该表必须像数据文件一样工作,除了数据库系统之外不会被任何其他东西写入。如果远程数据库发生任何更改,本地表中的数据完整性可能会受到破坏。

  • 在使用CONNECTION字符串时,密码中不能使用'@'字符。您可以通过使用CREATE SERVER语句创建服务器连接来绕过此限制。

  • insert_idtimestamp选项不会传播到数据提供程序。

  • FEDERATED表执行的任何DROP TABLE语句仅删除本地表,而不是远程表。

  • 不支持对FEDERATED表进行用户定义的分区。

18.8.4 FEDERATED 存储引擎资源

原文:dev.mysql.com/doc/refman/8.0/en/federated-storage-engine-resources.html

以下是可用于 FEDERATED 存储引擎的额外资源:

18.9 EXAMPLE存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/example-storage-engine.html

EXAMPLE存储引擎是一个什么都不做的存根引擎。它的目的是作为 MySQL 源代码中的一个示例,展示如何开始编写新的存储引擎。因此,它主要是为开发人员感兴趣。

如果您从源代码构建 MySQL,并希望启用EXAMPLE存储引擎,请使用CMake调用-DWITH_EXAMPLE_STORAGE_ENGINE选项。

要查看EXAMPLE引擎的源代码,请查看 MySQL 源代码分发中的storage/example目录。

当您创建一个EXAMPLE表时,不会创建任何文件。表中无法存储任何数据。检索将返回一个空结果。

mysql> CREATE TABLE test (i INT) ENGINE = EXAMPLE;
Query OK, 0 rows affected (0.78 sec)

mysql> INSERT INTO test VALUES(1),(2),(3);
ERROR 1031 (HY000): Table storage engine for 'test' doesn't »
                    have this option 
mysql> SELECT * FROM test;
Empty set (0.31 sec)

EXAMPLE存储引擎不支持索引。

EXAMPLE存储引擎不支持分区。

18.10 其他存储引擎

原文:dev.mysql.com/doc/refman/8.0/en/storage-engines-other.html

其他存储引擎可能来自已使用自定义存储引擎接口的第三方和社区成员。

不支持 MySQL 的第三方引擎。有关更多信息、文档、安装指南、错误报告或任何关于这些引擎的帮助或协助,请直接联系引擎开发者。

欲了解更多关于开发可与可插拔存储引擎架构一起使用的自定义存储引擎的信息,请参阅 MySQL 内部:编写自定义存储引擎。

18.11 MySQL 存储引擎架构概述

原文:dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html

18.11.1 可插拔存储引擎架构

18.11.2 共同的数据库服务器层

MySQL 可插拔存储引擎架构使数据库专业人员能够为特定应用需求选择专门的存储引擎,同时完全屏蔽了管理任何特定应用编码需求的需要。MySQL 服务器架构将应用程序员和数据库管理员与存储级别的所有低级实现细节隔离开来,提供一致且易于使用的应用模型和 API。因此,尽管不同存储引擎具有不同的功能,但应用程序被屏蔽免受这些差异的影响。

MySQL 可插拔存储引擎架构显示在图 18.3,“带有可插拔存储引擎的 MySQL 架构”中。

图 18.3 MySQL 架构与可插拔存储引擎

MySQL 架构图显示连接器、接口、可插拔存储引擎、带有文件和日志的文件系统。

可插拔存储引擎架构提供了一套标准的管理和支持服务,这些服务在所有底层存储引擎中都是共同的。存储引擎本身是数据库服务器的组件,实际上在物理服务器级别上执行对底层数据的操作。

这种高效且模块化的架构为那些希望专门针对特定应用需求(如数据仓库、事务处理或高可用性情况)的人提供了巨大的好处,同时享受利用独立于任何一个存储引擎的一组接口和服务的优势。

应用程序员和数据库管理员通过位于存储引擎之上的连接器 API 和服务层与 MySQL 数据库进行交互。如果应用程序的更改带来了需要更改底层存储引擎或添加一个或多个存储引擎以支持新需求的要求,那么不需要进行重大的编码或流程更改即可使事情正常运行。MySQL 服务器架构通过提供一致且易于使用的 API 来屏蔽应用程序免受存储引擎的底层复杂性。

18.11.1 可插拔存储引擎架构

原文:dev.mysql.com/doc/refman/8.0/en/pluggable-storage.html

MySQL 服务器使用可插拔存储引擎架构,允许将存储引擎加载到运行中的 MySQL 服务器中并从中卸载。

安装存储引擎

在使用存储引擎之前,必须使用INSTALL PLUGIN语句将存储引擎插件共享库加载到 MySQL 中。例如,如果EXAMPLE引擎插件命名为example,共享库命名为ha_example.so,则可以使用以下语句加载:

INSTALL PLUGIN example SONAME 'ha_example.so';

要安装可插拔存储引擎,插件文件必须位于 MySQL 插件目录中,并且发出INSTALL PLUGIN语句的用户必须对mysql.plugin表具有INSERT权限。

共享库必须位于 MySQL 服务器插件目录中,其位置由plugin_dir系统变量给出。

卸载存储引擎

要卸载存储引擎,请使用UNINSTALL PLUGIN语句:

UNINSTALL PLUGIN example;

如果卸载一个现有表需要的存储引擎,那些表将变得无法访问,但仍然存在于磁盘上(如果适用)。在卸载存储引擎之前,请确保没有表使用存储引擎。

18.11.2 通用数据库服务器层

原文:dev.mysql.com/doc/refman/8.0/en/pluggable-storage-common-layer.html

MySQL 可插拔存储引擎是 MySQL 数据库服务器中负责执行实际数据 I/O 操作的组件,同时启用和强制执行针对特定应用需求的某些功能集。使用特定存储引擎的一个主要好处是,你只会获得特定应用所需的功能,因此在数据库中的系统开销更少,最终结果是更高效和更高性能的数据库。这也是 MySQL 一直以来以高性能而闻名的原因之一,在行业标准基准测试中与专有的单体数据库相匹敌或超越。

从技术角度来看,存储引擎中有哪些独特的支持基础设施组件?一些关键的特性差异包括:

  • 并发性:一些应用程序对锁定要求更加精细(如行级锁)而另一些则不然。选择正确的锁定策略可以减少开销,从而提高整体性能。这个领域还包括支持诸如多版本并发控制或“快照”读取等功能。

  • 事务支持:并非每个应用程序都需要事务,但对于那些需要的应用程序,有非常明确定义的要求,如 ACID 兼容性等。

  • 引用完整性:需要服务器通过 DDL 定义的外键来强制执行关系数据库的引用完整性。

  • 物理存储:这涉及从表和索引的整体页面大小到用于存储数据的格式以及物理磁盘的一切。

  • 索引支持:不同的应用场景往往受益于不同的索引策略。每个存储引擎通常都有自己的索引方法,尽管一些(如 B 树索引)几乎适用于所有引擎。

  • 内存缓存:不同的应用程序对某些内存缓存策略的响应更好,因此尽管一些内存缓存对所有存储引擎都是通用的(例如用于用户连接的缓存),但其他的只有在特定存储引擎投入使用时才会被唯一定义。

  • 性能辅助:这包括用于并行操作的多个 I/O 线程,线程并发性,数据库检查点,批量插入处理等。

  • 其他目标特性:这可能包括对地理空间操作的支持,对某些数据操作的安全限制以及其他类似的功能。

每组可插拔存储引擎基础设施组件都旨在为特定应用程序提供一组选择性的优势。相反,避免一组组件功能有助于减少不必要的开销。可以说,了解特定应用程序的一组要求并选择适当的 MySQL 存储引擎对整个系统的效率和性能都会产生显著影响。

第十九章 复制

原文:dev.mysql.com/doc/refman/8.0/en/replication.html

目录

19.1 配置复制

19.1.1 基于二进制日志文件位置的复制配置概述

19.1.2 设置基于二进制日志文件位置的复制

19.1.3 使用全局事务标识符进行复制

19.1.4 在在线服务器上更改 GTID 模式

19.1.5 MySQL 多源复制

19.1.6 复制和二进制日志选项和变量

19.1.7 常见复制管理任务

19.2 复制实现

19.2.1 复制格式

19.2.2 复制通道

19.2.3 复制线程

19.2.4 中继日志和复制元数据存储库

19.2.5 服务器如何评估复制过滤规则

19.3 复制安全性

19.3.1 设置复制以使用加密连接

19.3.2 加密二进制日志文件和中继日志文件

19.3.3 复制权限检查

19.4 复制解决方案

19.4.1 使用复制进行备份

19.4.2 处理复制副本意外停止

19.4.3 监控基于行的复制

19.4.4 使用不同源和副本存储引擎进行复制

19.4.5 使用复制进行扩展

19.4.6 将不同数据库复制到不同副本

19.4.7 改善复制性能

19.4.8 在故障转移期间切换源

19.4.9 使用异步连接故障转移切换源和副本

19.4.10 半同步复制

19.4.11 延迟复制

19.5 复制注意事项和提示

19.5.1 复制功能和问题

19.5.2 MySQL 版本之间的复制兼容性

19.5.3 升级复制拓扑

19.5.4 复制故障排除

19.5.5 如何报告复制错误或问题

复制使得来自一个 MySQL 数据库服务器(称为源)的数据可以被复制到一个或多个 MySQL 数据库服务器(称为副本)上。默认情况下,复制是异步的;副本不需要永久连接以接收来自源端的更新。根据配置,可以复制所有数据库、选定的数据库,甚至是数据库中的选定表。

MySQL 中复制的优势包括:

  • 扩展解决方案 - 将负载分散在多个副本之间以提高性能。在这种环境中,所有写入和更新必须在源服务器上进行。然而,读取可以在一个或多个副本上进行。这种模型可以提高写入性能(因为源端专用于更新),同时大大提高跨越越来越多副本的读取速度。

  • 数据安全性 - 因为副本可以暂停复制过程,所以可以在副本上运行备份服务,而不会破坏相应的源数据。

  • 分析 - 实时数据可以在源端创建,而信息分析可以在副本上进行,而不会影响源端的性能。

  • 远程数据分发 - 可以使用复制在远程站点创建数据的本地副本,而无需永久访问源端。

有关如何在这种情况下使用复制的信息,请参阅第 19.4 节,“复制解决方案”。

MySQL 8.0 支持不同的复制方法。传统方法基于从源端二进制日志复制事件,并要求在源端和副本之间同步日志文件和位置。基于全局事务标识符(GTIDs)的新方法是事务性的,因此不需要处理日志文件或这些文件中的位置,这极大简化了许多常见的复制任务。使用 GTIDs 进行复制可以保证源端和副本之间的一致性,只要在源端提交的所有事务也已在副本上应用。有关 MySQL 中 GTIDs 和基于 GTID 的复制的更多信息,请参阅第 19.1.3 节,“使用全局事务标识符进行复制”。有关使用基于二进制日志文件位置的复制的信息,请参阅第 19.1 节,“配置复制”。

MySQL 中的复制支持不同类型的同步。最初的同步类型是单向异步复制,其中一个服务器充当源,而一个或多个其他服务器充当副本。这与NDB Cluster的同步复制形成对比(参见第二十五章,MySQL NDB Cluster 8.0)。在 MySQL 8.0 中,除了内置的异步复制外,还支持半同步复制。通过半同步复制,在源上执行的提交会在返回到执行事务的会话之前阻塞,直到至少一个副本确认已接收并记录了事务的事件;请参见第 19.4.10 节,“半同步复制”。MySQL 8.0 还支持延迟复制,使得副本故意落后源至少指定的时间量;请参见第 19.4.11 节,“延迟复制”。对于需要同步复制的情况,请使用 NDB Cluster(参见第二十五章,MySQL NDB Cluster 8.0)。

有许多可用的解决方案可用于设置服务器之间的复制,最佳使用方法取决于数据的存在以及您正在使用的引擎类型。有关可用选项的更多信息,请参见第 19.1.2 节,“设置基于二进制日志文件位置的复制”。

复制格式有两种核心类型,基于语句的复制(SBR),它复制整个 SQL 语句,以及基于行的复制(RBR),它只复制已更改的行。您还可以使用第三种类型,混合基于复制(MBR)。有关不同复制格式的更多信息,请参见第 19.2.1 节,“复制格式”。

复制通过许多不同的选项和变量进行控制。有关更多信息,请参见第 19.1.6 节,“复制和二进制日志选项和变量”。还可以应用额外的安全措施到复制拓扑中,如第 19.3 节,“复制安全性”中所述。

你可以使用复制来解决许多不同的问题,包括性能、支持不同数据库的备份,以及作为缓解系统故障的更大解决方案的一部分。有关如何解决这些问题的信息,请参见第 19.4 节,“复制解决方案”。

关于不同数据类型和语句在复制过程中的处理方式的注释和提示,包括复制功能的详细信息、版本兼容性、升级以及潜在问题及其解决方法,请参见第 19.5 节,“复制注释和提示”。对于那些对 MySQL 复制新手经常提出的一些问题的答案,请参见第 A.14 节,“MySQL 8.0 FAQ: 复制”。

关于复制实现、复制工作原理、二进制日志的过程和内容、后台线程以及用于决定如何记录和复制语句的规则的详细信息,请参见第 19.2 节,“复制实现”。

19.1 配置复制

原文:dev.mysql.com/doc/refman/8.0/en/replication-configuration.html

19.1.1 基于二进制日志文件位置的复制配置概述

19.1.2 设置基于二进制日志文件位置的复制

19.1.3 具有全局事务标识符的复制

19.1.4 在在线服务器上更改 GTID 模式

19.1.5 MySQL 多源复制

19.1.6 复制和二进制日志选项和变量

19.1.7 常见的复制管理任务

本节描述了如何配置 MySQL 中可用的不同类型的复制,并包括复制环境所需的设置和配置,包括为创建新的复制环境提供逐步说明。本节的主要组成部分包括:

  • 对于使用二进制日志文件位置设置两个或更多服务器进行复制的指南,请参阅第 19.1.2 节,“设置基于二进制日志文件位置的复制”,处理服务器的配置并提供在源和副本之间复制数据的方法。

  • 对于使用 GTID 事务设置两个或更多服务器进行复制的指南,请参阅第 19.1.3 节,“具有全局事务标识符的复制”,处理服务器的配置。

  • 二进制日志中记录的事件使用多种格式。这些被称为基于语句的复制(SBR)或基于行的复制(RBR)。第三种类型,混合格式复制(MIXED),在适当时自动使用 SBR 或 RBR 复制以充分利用 SBR 和 RBR 格式的优势。不同的格式在第 19.2.1 节,“复制格式”中讨论。

  • 提供有关适用于复制的不同配置选项和变量的详细信息在第 19.1.6 节,“复制和二进制日志选项和变量”中。

  • 一旦启动,复制过程应该需要很少的管理或监控。但是,对于您可能想要执行的常见任务的建议,请参阅第 19.1.7 节,“常见的复制管理任务”。

19.1.1 基于二进制日志文件位置的复制配置概述

原文:dev.mysql.com/doc/refman/8.0/en/binlog-replication-configuration-overview.html

本节描述了基于二进制日志文件位置方法的 MySQL 服务器之间的复制,其中作为源(数据库更改发生的地方)运行的 MySQL 实例将更新和更改写入二进制日志作为“事件”。二进制日志中的信息根据记录的数据库更改以不同的日志格式存储。复制品被配置为从源读取二进制日志,并在复制品的本地数据库上执行二进制日志中的事件。

每个复制品接收二进制日志的整个内容副本。复制品有责任决定应执行二进制日志中的哪些语句。除非另有规定,否则源的二进制日志中的所有事件都将在复制品上执行。如果需要,可以配置复制品仅处理适用于特定数据库或表的事件。

重要提示

无法配置源仅记录某些事件。

每个复制品保留二进制日志坐标的记录:它已从源读取和处理的文件名和文件中位置。这意味着多个复制品可以连接到源并在同一二进制日志的不同部分执行。由于复制品控制此过程,因此可以连接和断开单个复制品而不影响源的操作。此外,因为每个复制品记录了二进制日志中的当前位置,所以可以断开复制品,重新连接,然后恢复处理。

源和每个复制品必须配置一个唯一的 ID(使用server_id系统变量)。此外,每个复制品必须配置有关源主机名、日志文件名和文件中位置的信息。这些细节可以通过 MySQL 会话内的CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)在复制品上进行控制。这些细节存储在复制品的连接元数据存储库中(参见第 19.2.4 节,“中继日志和复制元数据存储库”)。

19.1.2 设置基于二进制日志文件位置的复制

原文:dev.mysql.com/doc/refman/8.0/en/replication-howto.html

19.1.2.1 设置复制源配置

19.1.2.2 设置副本配置

19.1.2.3 为复制创建用户

19.1.2.4 获取复制源的二进制日志坐标

19.1.2.5 选择数据快照方法

19.1.2.6 设置副本

19.1.2.7 在副本上设置源配置

19.1.2.8 将副本添加到复制环境

本节描述了如何设置 MySQL 服务器以使用基于二进制日志文件位置的复制。有许多不同的设置复制的方法,要使用的确切方法取决于您如何设置复制,以及源数据库中是否已经有要复制的数据。

提示

要部署多个 MySQL 实例,您可以使用 InnoDB Cluster,它使您能够轻松管理一组 MySQL 服务器实例在 MySQL Shell 中。InnoDB Cluster 将 MySQL Group Replication 包装在一个编程环境中,使您可以轻松部署一组 MySQL 实例以实现高可用性。此外,InnoDB Cluster 与 MySQL Router 无缝接口,使您的应用程序可以连接到集群而无需编写自己的故障转移过程。然而,对于不需要高可用性的类似用例,您可以使用 InnoDB ReplicaSet。有关 MySQL Shell 的安装说明,请参见这里。

有一些通用任务适用于所有设置:

  • 在源端,您必须确保启用了二进制日志记录,并配置一个唯一的服务器 ID。这可能需要重新启动服务器。参见 Section 19.1.2.1, “设置复制源配置”。

  • 在每个要连接到源的副本上,您必须配置一个唯一的服务器 ID。这可能需要重新启动服务器。参见 Section 19.1.2.2, “设置副本配置”。

  • 可选地,为您的副本创建一个单独的用户,用于在复制时与源进行身份验证以读取二进制日志。参见第 19.1.2.3 节,“为复制创建用户”。

  • 在创建数据快照或启动复制过程之前,在源上记录二进制日志中的当前位置。在配置副本时,您需要这些信息,以便副本知道在二进制日志中从哪里开始执行事件。参见第 19.1.2.4 节,“获取复制源二进制日志坐标”。

  • 如果您已经在源上有数据并希望使用它来同步副本,您需要创建一个数据快照将数据复制到副本。您正在使用的存储引擎会影响您如何创建快照。当您使用MyISAM时,您必须停止在源上处理语句以获取读锁,然后获取其当前的二进制日志坐标并转储其数据,然后允许源继续执行语句。如果您不停止执行语句,则数据转储和源状态信息将不匹配,导致副本上的数据库不一致或损坏。有关复制MyISAM源的更多信息,请参见第 19.1.2.4 节,“获取复制源二进制日志坐标”。如果您使用InnoDB,则不需要读锁,只需一个足够长的事务来传输数据快照即可。有关更多信息,请参见第 17.19 节,“InnoDB 和 MySQL 复制”。

  • 配置副本以设置连接到源的设置,如主机名、登录凭据和二进制日志文件名和位置。参见第 19.1.2.7 节,“在副本上设置源配置”。

  • 根据您的系统,在源和副本上实施特定于复制的安全措施。参见第 19.3 节,“复制安全”。

注意

设置过程中的某些步骤需要SUPER权限。如果您没有此权限,则可能无法启用复制。

配置基本选项后,选择您的场景:

  • 要为不包含任何数据的新源和副本的新安装设置复制,请参阅第 19.1.2.6.1 节,“使用新源和副本设置复制”。

  • 要设置使用现有 MySQL 服务器数据进行新源的复制,请参阅第 19.1.2.6.2 节,“使用现有数据设置复制”。

  • 要向现有复制环境添加副本,请参阅第 19.1.2.8 节,“向复制环境添加副本”。

在管理 MySQL 复制服务器之前,请阅读本章的全部内容,并尝试执行第 15.4.1 节,“用于控制源服务器的 SQL 语句”和第 15.4.2 节,“用于控制副本服务器的 SQL 语句”中提到的所有语句,并熟悉第 19.1.6 节,“复制和二进制日志选项和变量”中描述的复制启动选项。

原文:dev.mysql.com/doc/refman/8.0/en/replication-howto-masterbaseconfig.html

19.1.2.1 设置复制源配置

要配置源端使用基于二进制日志文件位置的复制,您必须确保启用了二进制日志记录,并建立一个唯一的服务器 ID。

在复制拓扑结构中,每个服务器都必须配置一个唯一的服务器 ID,您可以使用server_id系统变量来指定。该服务器 ID 用于标识复制拓扑结构中的各个服务器,必须是介于 1 和(2³²)−1 之间的正整数。从 MySQL 8.0 开始,默认的server_id值为 1。您可以通过发出类似以下语句来动态更改server_id的值:

SET GLOBAL server_id = 2;

您可以自行组织和选择服务器 ID,只要每个服务器 ID 与复制拓扑结构中任何其他服务器正在使用的每个其他服务器 ID 不同即可。请注意,如果以前为服务器 ID 设置了值 0(这是早期版本的默认值),则必须重新启动服务器以使用新的非零服务器 ID 初始化源端。否则,当您更改服务器 ID 时,���非进行其他需要重新启动的配置更改,否则不需要重新启动服务器。

源端需要启用二进制日志记录,因为二进制日志是从源端到其副本进行更改复制的基础。二进制日志记录默认启用(log_bin系统变量设置为 ON)。--log-bin选项告诉服务器要使用的二进制日志文件的基本名称。建议您指定此选项,以便为二进制日志文件指定非默认基本名称,这样如果主机名更改,您可以轻松地继续使用相同的二进制日志文件名(参见 Section B.3.7, “Known Issues in MySQL”)。如果之前在源端使用--skip-log-bin选项禁用了二进制日志记录,则必须在不带此选项的情况下重新启动服务器以启用它。

注意

以下选项也会影响源端:

  • 在使用带有事务的InnoDB的复制设置中,为了获得最大的耐久性和一致性,您应该在源端的my.cnf文件中使用innodb_flush_log_at_trx_commit=1sync_binlog=1

  • 确保源端未启用skip_networking系统变量。如果网络已禁用,则副本无法与源端通信,复制将失败。

原文:dev.mysql.com/doc/refman/8.0/en/replication-howto-slavebaseconfig.html

19.1.2.2 设置复制品配置

每个复制品必须具有唯一的服务器 ID,由server_id系统变量指定。如果您正在设置多个复制品,则每个复制品必须具有与源和任何其他复制品不同的唯一server_id值。如果复制品的服务器 ID 尚未设置,或当前值与您为源或其他复制品选择的值冲突,则必须更改它。

默认server_id值为 1。您可以通过发出类似以下语句来动态更改server_id值:

SET GLOBAL server_id = 21;

请注意,服务器 ID 的值为 0 会阻止复制品连接到源。如果该服务器 ID 值(这是早期版本中的默认值)以前已设置,则必须重新启动服务器以使用新的非零服务器 ID 初始化复制品。否则,当您更改服务器 ID 时,不需要重新启动服务器,除非进行其他需要重新启动的配置更改。例如,如果服务器上已禁用二进制日志记录,并且您希望在复制品上启用它,则需要重新启动服务器才能启用此功能。

如果要关闭复制品服务器,可以编辑配置文件的[mysqld]部分以指定唯一的服务器 ID。例如:

[mysqld]
server-id=21

所有服务器默认启用二进制日志记录。复制品不需要启用二进制日志记录才能进行复制。但是,复制品上启用二进制日志记录意味着复制品的二进制日志可用于数据备份和崩溃恢复。已启用二进制日志记录的复制品也可以用作更复杂复制拓扑的一部分。例如,您可能希望使用此链接安排设置复制服务器:

A -> B -> C

这里,A充当复制品B的源,而B充当复制品C的源。为了使其正常工作,B必须既是源又是复制品。从A接收到的更新必须由B记录到其二进制日志中,以便传递给C。除了二进制日志记录外,此复制拓扑结构需要启用系统变量log_replica_updates(从 MySQL 8.0.26 开始)或log_slave_updates(在 MySQL 8.0.26 之前)才能正常工作。启用复制更新后,复制品会将从源接收并由复制品的 SQL 线程执行的更新写入复制品自己的二进制日志中。系统变量log_replica_updateslog_slave_updates默认启用。

如果需要在复制品上禁用二进制日志记录或复制更新记录,可以通过为复制品指定--skip-log-bin--log-replica-updates=OFF--log-slave-updates=OFF选项来实现。如果决定在复制品上重新启用这些功能,请删除相关选项并重新启动服务器。

原文:dev.mysql.com/doc/refman/8.0/en/replication-howto-repuser.html

19.1.2.3 为复制创建用户

每个副本使用 MySQL 用户名和密码连接到源端,因此必须在源端上有一个副本可以使用的用户帐户。当您设置副本时,通过CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)指定用户名称。任何帐户都可以用于此操作,只要已授予REPLICATION SLAVE权限。您可以选择为每个副本创建不同的帐户,或者使用相同的帐户连接到源端以供每个副本使用。

尽管您不必专门为复制创建帐户,但您应该知道复制用户名和密码以明文形式存储在复制连接元数据存储库mysql.slave_master_info中(参见 Section 19.2.4.2,“复制元数据存储库”)。因此,您可能希望创建一个仅具有复制过程权限的单独帐户,以最大程度地减少其他帐户遭受威胁的可能性。

要创建一个新帐户,请使用CREATE USER。要为此帐户授予复制所需的权限,请使用GRANT语句。如果您仅为复制目的创建一个帐户,则该帐户只需要REPLICATION SLAVE权限。例如,要设置一个名为repl的新用户,该用户可以从example.com域内的任何主机连接进行复制,请在源端执行以下语句:

mysql> CREATE USER 'repl'@'%.example.com' IDENTIFIED BY '*password*';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.example.com';

有关用户帐户操作语句的更多信息,请参见 Section 15.7.1,“帐户管理语句”。

重要提示

要使用使用caching_sha2_password插件进行身份验证的用户帐户连接到源,您必须按照 Section 19.3.1, “Setting Up Replication to Use Encrypted Connections”中描述的设置安装安全连接,或者启用不加密的连接以支持使用 RSA 密钥对进行密码交换。caching_sha2_password认证插件是从 MySQL 8.0 开始新用户的默认选项(有关详细信息,请参见 Section 8.4.1.2, “Caching SHA-2 Pluggable Authentication”)。如果您创建或用于复制的用户帐户(由MASTER_USER选项指定)使用此认证插件,并且您没有使用安全连接,则必须启用基于 RSA 密钥对的密码交换以成功连接。

原文:dev.mysql.com/doc/refman/8.0/en/replication-howto-masterstatus.html

19.1.2.4 获取复制源二进制日志坐标

要配置副本以在正确位置开始复制过程,您需要记录源在其二进制日志中的当前坐标。

警告

此过程使用FLUSH TABLES WITH READ LOCK,会阻塞InnoDB表的COMMIT操作。

如果您计划关闭源以创建数据快照,则可以选择跳过此过程,而是将二进制日志索引文件的副本与数据快照一起存储。在那种情况下,源在重新启动时会创建一个新的二进制日志文件。因此,副本必须开始复制过程的源二进制日志坐标是该新文件的开头,即在复制的二进制日志索引文件中列出的文件之后的源上的下一个二进制日志文件。

要获取源二进制日志坐标,请按照以下步骤操作:

  1. 在源上启动一个会话,通过命令行客户端连接到它,并通过执行FLUSH TABLES WITH READ LOCK语句刷新所有表并阻止写入语句:

    mysql> FLUSH TABLES WITH READ LOCK;
    

    警告

    保持发出FLUSH TABLES语句的客户端运行,以使读锁保持生效。如果退出客户端,则锁将被释放。

  2. 在源的另一个会话中,使用SHOW MASTER STATUS语句确定当前二进制日志文件名和位置:

    mysql> SHOW MASTER STATUS\G
    *************************** 1\. row ***************************
                 File: mysql-bin.000003
             Position: 73
         Binlog_Do_DB: test
     Binlog_Ignore_DB: manual, mysql
    Executed_Gtid_Set: 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5 1 row in set (0.00 sec)
    

    File列显示日志文件的名称,Position列显示文件内的位置。在此示例中,二进制日志文件为mysql-bin.000003,位置为 73。记录这些值。在设置副本时,您将需要它们。它们代表副本应开始处理源的新更新的复制坐标。

    如果源先前已禁用二进制日志记录运行,则SHOW MASTER STATUSmysqldump --master-data显示的日志文件名和位置值为空。在这种情况下,您稍后在指定源的二进制日志文件和位置时需要使用的值是空字符串('')和4

您现在拥有启用副本从源的二进制日志中正确位置开始读取所需的信息。

下一步取决于您在源端是否有现有数据。请选择以下选项之一:

  • 如果您有现有数据需要在开始复制之前与副本同步,请保持客户端运行,以便锁定保持在原位。这样可以防止进行进一步的更改,从而使复制到副本的数据与源数据同步。继续查看 Section 19.1.2.5, “选择数据快照方法”。

  • 如果您正在设置新的源和副本组合,您可以退出第一个会话以释放读锁。查看 Section 19.1.2.6.1, “使用新源和副本设置复制”以了解如何继续。

原文:dev.mysql.com/doc/refman/8.0/en/replication-snapshot-method.html

19.1.2.5 选择数据快照方法

如果源数据库包含现有数据,则需要将这些数据复制到每个副本中。有不同的方法可以从源数据库中导出数据。以下部分描述了可能的选项。

要选择适当的数据库转储方法,请在以下选项之间进行选择:

  • 使用mysqldump工具创建要复制的所有数据库的转储。这是推荐的方法,特别是在使用InnoDB时。

  • 如果您的数据库存储在二进制可移植文件中,则可以将原始数据文件复制到副本中。这可能比使用mysqldump并在每个副本上导入文件更有效,因为在重放INSERT语句时跳过更新索引的开销。对于诸如InnoDB之类的存储引擎,不建议这样做。

  • 使用 MySQL Server 的克隆插件将所有数据从现有副本传输到克隆副本。有关使用此方法的说明,请参见 Section 7.6.7.7, “Cloning for Replication”。

提示

要部署多个 MySQL 实例,可以使用 InnoDB Cluster,它使您能够轻松管理一组 MySQL 服务器实例在 MySQL Shell 中。InnoDB Cluster 在一个编程环境中包装了 MySQL Group Replication,使您可以轻松部署一组 MySQL 实例以实现高可用性。此外,InnoDB Cluster 与 MySQL Router 无缝接口,使您的应用程序可以连接到集群而无需编写自己的故障转移过程。然而,对于不需要高可用性的类似用例,您可以使用 InnoDB ReplicaSet。有关 MySQL Shell 的安装说明,请参见此处。

19.1.2.5.1 使用 mysqldump 创建数据快照

要在现有源数据库中创建数据快照,请使用mysqldump工具。完成数据转储后,在启动复制过程之前将这些数据导入副本。

以下示例将所有数据库转储到名为dbdump.db的文件中,并包括--master-data选项,该选项会自动附加在副本上启动复制过程所需的CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句:

$> mysqldump --all-databases --master-data > dbdump.db

注意

如果不使用--master-data,则需要在单独的会话中手动锁定所有表。参见 Section 19.1.2.4, “Obtaining the Replication Source Binary Log Coordinates”。

可以使用mysqldump工具排除转储中的某些数据库。如果要选择要包含在转储中的数据库,请不要使用--all-databases。选择以下选项之一:

  • 使用--ignore-table选项排除数据库中的所有表。

  • 只命名要转储的数据库,使用--databases选项。

注意

默认情况下,如果源端使用 GTIDs(gtid_mode=ON),mysqldump 在转储输出中包含源端gtid_executed集合中的 GTIDs,以将其添加到副本端的gtid_purged集合中。如果只转储特定数据库或表,重要的是要注意,mysqldump 包含的值包括源端gtid_executed集合中的所有事务的 GTIDs,即使这些事务更改了数据库的被抑制部分,或者服务器上的其他未包含在部分转储中的数据库。查看 mysqldump 的--set-gtid-purged选项的描述,以找到您正在使用的 MySQL 服务器版本的默认行为结果,以及如何更改行为,如果此结果不适合您的情况。

有关更多信息,请参阅 Section 6.5.4, “mysqldump — A Database Backup Program”。

要导入数据,可以将转储文件复制到副本,或者在远程连接到副本时从源文件访问。

19.1.2.5.2 使用原始数据文件创建数据快照

本节描述了如何使用组成数据库的原始文件创建数据快照。使用这种方法时,对于使用具有复杂缓存或日志算法的存储引擎的表,需要额外的步骤来生成完美的“时间点”快照:初始复制命令可能会遗漏缓存信息和日志更新,即使你已经获得了全局读锁。存储引擎对此的响应取决于其崩溃恢复能力。

如果使用InnoDB表,可以使用 MySQL Enterprise Backup 组件中的mysqlbackup命令生成一致的快照。该命令记录了与要在副本上使用的快照对应的日志名称和偏移量。MySQL Enterprise Backup 是作为 MySQL Enterprise 订阅的一部分包含的商业产品。详细信息请参见 Section 32.1, “MySQL Enterprise Backup Overview”。

这种方法在源和副本具有不同值ft_stopword_fileft_min_word_lenft_max_word_len时也无法可靠工作,如果你要复制具有全文索引的表。

假设上述例外情况不适用于你的数据库,使用冷备份技术获取InnoDB表的可靠二进制快照:对 MySQL Server 进行慢关闭,然后手动复制数据文件。

当你的 MySQL 数据文件存在于单个文件系统上时,可以使用标准文件复制工具如cpcopy,远程复制工具如scprsync,压缩工具如ziptar,或文件系统快照工具如dump来创建MyISAM表的原始数据快照。如果只复制特定数据库,只复制与这些表相关的文件。对于InnoDB,除非启用了innodb_file_per_table选项,否则所有数据库中的所有表都存储在系统表空间文件中。

以下文件不需要用于复制:

  • mysql数据库相关的文件。

  • 副本的连接元数据存储库文件master.info,如果使用;现在已弃用此文件的使用(参见 Section 19.2.4, “Relay Log and Replication Metadata Repositories”)。

  • 源的二进制日志文件,除非您打算使用它来定位副本的源二进制日志坐标时,不包括二进制日志索引文件。

  • 任何中继日志文件。

根据您是否使用InnoDB表,选择以下操作之一:

如果您正在使用InnoDB表,并且为了获得最一致的原始数据快照结果,请在过程中关闭源服务器,具体操作如下:

  1. 获取读锁并获取源的状态。参见第 19.1.2.4 节,“获取复制源二进制日志坐标”。

  2. 在单独的会话中,关闭源服务器:

    $> mysqladmin shutdown
    
  3. 复制 MySQL 数据文件。以下示例展示了常见的操作方式。您只需选择其中一种:

    $> tar cf */tmp/db.tar* *./data*
    $> zip -r */tmp/db.zip* *./data*
    $> rsync --recursive *./data* */tmp/dbdata*
    
  4. 重新启动源服务器。

如果您没有使用InnoDB表,您可以从源获取系统快照而无需关闭服务器,具体步骤如下:

  1. 获取读锁并获取源的状态。参见第 19.1.2.4 节,“获取复制源二进制日志坐标”。

  2. 复制 MySQL 数据文件。以下示例展示了常见的操作方式。您只需选择其中一种:

    $> tar cf */tmp/db.tar* *./data*
    $> zip -r */tmp/db.zip* *./data*
    $> rsync --recursive *./data* */tmp/dbdata*
    
  3. 在获取读锁的客户端中,释放锁:

    mysql> UNLOCK TABLES;
    

创建数据库的归档或副本后,在启动复制过程之前将文件复制到每个副本。

原文:dev.mysql.com/doc/refman/8.0/en/replication-setup-replicas.html

19.1.2.6 设置副本

以下各节描述了如何设置副本。在继续之前,请确保您已经:

  • 配置了具有必要配置属性的源。请参阅 Section 19.1.2.1, “设置复制源配置”。

  • 获取源状态信息,或在数据快照期间关闭时制作源的二进制日志索引文件的副本。请参阅 Section 19.1.2.4, “获取复制源二进制日志坐标”。

  • 在源上释放读锁:

    mysql> UNLOCK TABLES;
    
  • 在副本上编辑了 MySQL 配置。请参阅 Section 19.1.2.2, “设置副本配置”。

接下来的步骤取决于您是否有要导入到副本的现有数据。有关更多信息,请参阅 Section 19.1.2.5, “选择数据快照方法”。选择以下之一:

  • 如果没有要导入的数据库快照,请参阅 Section 19.1.2.6.1, “使用新源和副本设置复制”。

  • 如果您有要导入的数据库快照,请参阅 Section 19.1.2.6.2, “使用现有数据设置复制”。

19.1.2.6.1 使用新源和副本设置复制

如果没有以前数据库的快照要导入,请配置副本以从新源开始复制。

要在源和新副本之间设置复制:

  1. 启动副本。

  2. 在副本上执行CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句,设置源配置。请参阅 Section 19.1.2.7, “在副本上设置源配置”。

在每个副本上执行以下副本设置步骤。

如果您正在设置新服务器,但有来自不同服务器的现有数据库转储,想要加载到您的复制配置中,也可以使用此方法。通过将数据加载到新源,数据会自动复制到副本。

如果您正在使用来自不同现有数据库服务器的数据创建新源来设置新的复制环境,请在新源上运行从该服务器生成的转储文件。数据库更新会自动传播到副本:

$> mysql -h source < fulldb.dump
19.1.2.6.2 使用现有数据设置复制

在使用现有数据设置复制时,在开始复制之前,将快照从源传输到副本。将数据导入副本的过程取决于您如何在源上创建数据的快照。

提示

要部署多个 MySQL 实例,您可以使用 InnoDB Cluster,它使您能够轻松管理一组 MySQL 服务器实例在 MySQL Shell 中。InnoDB Cluster 在一个编程环境中封装了 MySQL Group Replication,使您可以轻松部署一组 MySQL 实例以实现高可用性。此外,InnoDB Cluster 与 MySQL Router 无缝接口,使您的应用程序可以连接到集群而无需编写自己的故障转移过程。然而,对于不需要高可用性的类似用例,您可以使用 InnoDB ReplicaSet。有关 MySQL Shell 的安装说明,请参见这里。

注意

如果要复制的复制源服务器或现有副本在创建新副本时有任何计划事件,请确保在启动新副本之前将其禁用。如果新副本上运行的事件已在源上运行,则重复的操作会导致错误。事件调度程序由event_scheduler系统变量控制,默认情况下从 MySQL 8.0 开始为ON,因此在新副本启动时默认情况下会运行在原始服务器上活动的事件。要停止新副本上的所有事件运行,请将event_scheduler系统变量设置为OFFDISABLED。或者,您可以使用ALTER EVENT语句将单独的事件设置为DISABLEDISABLE ON SLAVE以防止它们在新副本上运行。您可以使用SHOW语句或信息模式EVENTS表列出服务器上的事件。有关更多信息,请参见 Section 19.5.1.16, “Replication of Invoked Features”。

作为在这种方式下创建新副本的替代方案,MySQL Server 的克隆插件可以用于将所有数据和复制设置从现有副本传输到克隆中。有关使用此方法的说明,请参见 Section 7.6.7.7, “复制用于克隆”。

按照以下步骤设置使用现有数据的复制:

  1. 如果您使用 MySQL Server 的克隆插件从现有副本创建克隆(参见 Section 7.6.7.7, “复制用于克隆”),则数据已经传输。否则,使用以下方法之一将数据导入到副本中。

    1. 如果您使用了mysqldump,启动副本服务器,确保使用--skip-slave-start选项或从 MySQL 8.0.24 开始,使用skip_slave_start系统变量来防止复制启动。然后导入转储文件:

      $> mysql < fulldb.dump
      
    2. 如果您使用原始数据文件创建快照,请将数据文件提取到副本的数据目录中。例如:

      $> tar xvf dbdump.tar
      

      您可能需要设置文件的权限和所有权,以便副本服务器可以访问和修改它们。然后启动副本服务器,确保使用--skip-slave-start选项或从 MySQL 8.0.24 开始,使用skip_slave_start系统变量来防止复制启动。

  2. 使用源的复制坐标配置副本。这告诉副本需要开始复制的二进制日志文件和文件内位置。还要使用源的登录凭据和主机名配置副本。有关所需的CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的更多信息,请参见 Section 19.1.2.7, “在副本上设置源配置”。

  3. 通过发出START REPLICA(或在 MySQL 8.0.22 之前,START SLAVE)语句来启动复制线程。

完成此过程后,副本将连接到源并复制自快照以来在源上发生的任何更新。如果由于任何原因副本无法复制,则会向副本的错误日志发出错误消息。

复制品使用其连接元数据存储库和应用程序元数据存储库中记录的信息来跟踪已处理源二进制日志的数量。从 MySQL 8.0 开始,默认情况下,这些存储库是mysql数据库中名为slave_master_infoslave_relay_log_info的表。除非您确切知道自己在做什么并完全了解其影响,否则不要删除或编辑这些表。即使在这种情况下,最好使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句来更改复制参数。复制品使用语句中指定的值来自动更新复制元数据存储库。有关更多信息,请参见第 19.2.4 节,“中继日志和复制元数据存储库”。

注意

复制品的连接元数据存储库的内容会覆盖在命令行或my.cnf中指定的一些服务器选项。详细信息请参见第 19.1.6 节,“复制和二进制日志选项和变量”。

源的单个快照足以供多个复制品使用。要设置额外的复制品,请使用相同的源快照,并按照刚才描述的复制品部分的步骤进行操作。

原文:dev.mysql.com/doc/refman/8.0/en/replication-howto-slaveinit.html

19.1.2.7 在副本上设置源配置

要设置副本与源通信以进行复制,请使用必要的连接信息配置副本。为此,在副本上执行CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前),将选项值替换为与您系统相关的实际值:

mysql> CHANGE MASTER TO
 ->     MASTER_HOST='*source_host_name*',
 ->     MASTER_USER='*replication_user_name*',
 ->     MASTER_PASSWORD='*replication_password*',
 ->     MASTER_LOG_FILE='*recorded_log_file_name*',
 ->     MASTER_LOG_POS=*recorded_log_position*;

Or from MySQL 8.0.23:
mysql> CHANGE REPLICATION SOURCE TO
 ->     SOURCE_HOST='*source_host_name*',
 ->     SOURCE_USER='*replication_user_name*',
 ->     SOURCE_PASSWORD='*replication_password*',
 ->     SOURCE_LOG_FILE='*recorded_log_file_name*',
 ->     SOURCE_LOG_POS=*recorded_log_position*;

注意

复制不能使用 Unix 套接字文件。您必须能够使用 TCP/IP 连接到源 MySQL 服务器。

CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句还有其他选项。例如,可以使用 SSL 设置安全复制。有关选项的完整列表以及有关字符串值选项的最大允许长度的信息,请参阅第 15.4.2.1 节“CHANGE MASTER TO Statement”。

重要提示

如第 19.1.2.3 节“为复制创建用户”中所述,如果您未使用安全连接,并且SOURCE_USER | MASTER_USER选项中指定的用户帐户使用caching_sha2_password插件进行身份验证(从 MySQL 8.0 开始的默认设置),则必须在CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句中指定SOURCE_PUBLIC_KEY_PATH | MASTER_PUBLIC_KEY_PATHGET_SOURCE_PUBLIC_KEY | GET_MASTER_PUBLIC_KEY选项,以启用基于 RSA 密钥对的密码交换。

原文:dev.mysql.com/doc/refman/8.0/en/replication-howto-additionalslaves.html

19.1.2.8 向复制环境添加复制实例

您可以在不停止源服务器的情况下向现有复制配置中添加另一个复制实例。为此,您可以通过复制现有复制实例的数据目录来设置新的复制实例,并为新的复制实例指定不同的服务器 ID(由用户指定)和服务器 UUID(在启动时生成)。

注意

如果您要复制以创建新的复制实例的复制源服务器或现有复制实例具有任何计划事件,请确保在启动新的复制实例之前将这些事件禁用。如果新的复制实例上运行的事件已经在源上运行过,则重复的操作会导致错误。事件调度程序由event_scheduler系统变量控制,默认情况下从 MySQL 8.0 开始为ON,因此在新的复制实例启动时默认情况下会运行在原始服务器上活动的事件。要停止新的复制实例上的所有事件运行,请在新的复制实例上将event_scheduler系统变量设置为OFFDISABLED。或者,您可以使用ALTER EVENT语句将单个事件设置为DISABLEDISABLE ON SLAVE以防止它们在新的复制实例上运行。您可以使用SHOW语句或信息模式EVENTS表列出服务器上的事件。有关更多信息,请参见 Section 19.5.1.16, “Replication of Invoked Features”。

作为以这种方式创建新的复制实例的替代方法,MySQL 服务器的克隆插件可用于将所有数据和复制设置从现有复制实例传输到克隆实例。有关使用此方法的说明,请参见 Section 7.6.7.7, “Cloning for Replication”。

要复制现有的复制实例而不进行克隆,请按照以下步骤操作:

  1. 停止现有的复制实例并记录复制实例状态信息,特别是源二进制日志文件和中继日志文件位置。您可以通过性能模式复制表(请参阅 Section 29.12.11, “Performance Schema Replication Tables”)查看复制实例状态,或通过以下方式发出SHOW REPLICA STATUS

    mysql> STOP SLAVE;
    mysql> SHOW SLAVE STATUS\G
    Or from MySQL 8.0.22:
    mysql> STOP REPLICA;
    mysql> SHOW REPLICA STATUS\G
    
  2. 关闭现有的复制实例:

    $> mysqladmin shutdown
    
  3. 将现有副本的数据目录复制到新副本,包括日志文件和中继日志文件。您可以通过使用tarWinZip创建存档,或者通过使用cprsync等工具执行直接复制来完成此操作。

    重要

    • 在复制之前,请验证所有与现有副本相关的文件实际上是否存储在数据目录中。例如,InnoDB系统表空间、撤消表空间和重做日志可能存储在其他位置。InnoDB表空间文件和文件表空间可能已在其他目录中创建。副本的二进制日志和中继日志可能在数据目录之外的自己的目录中。检查为现有副本设置的系统变量,并查找是否已指定任何替代路径。如果找到任何内容,请将这些目录一并复制过去。

    • 在复制过程中,如果文件用于复制元数据存储库(请参阅第 19.2.4 节,“中继日志和复制元数据存储库”),请确保还将这些文件从现有副本复制到新副本。如果表用于存储库,这是从 MySQL 8.0 开始的默认设置,则这些表位于数据目录中。

    • 复制后,从新副本的数据目录副本中删除auto.cnf文件,以便新副本使用不同生成的服务器 UUID 启动。服务器 UUID 必须是唯一的。

    添加新副本时遇到的常见问题是,新副本失败,并显示一系列警告和错误消息,例如:

    071118 16:44:10 [Warning] Neither --relay-log nor --relay-log-index were used; so
    replication may break when this MySQL server acts as a replica and has his hostname
    changed!! Please use '--relay-log=*new_replica_hostname*-relay-bin' to avoid this problem.
    071118 16:44:10 [ERROR] Failed to open the relay log './*old_replica_hostname*-relay-bin.003525'
    (relay_log_pos 22940879)
    071118 16:44:10 [ERROR] Could not find target log during relay log initialization
    071118 16:44:10 [ERROR] Failed to initialize the master info structure
    

    如果未指定relay_log系统变量,则可能会出现此情况,因为中继日志文件的文件名中包含主机名。如果未使用relay_log_index系统变量,则中继日志索引文件也是如此。有关这些变量的更多信息,请参见第 19.1.6 节,“复制和二进制日志选项和变量”。

    为避免此问题,在新的复制品上使用与现有复制品上使用的relay_log相同的值。如果在现有复制品上未显式设置此选项,请使用*existing_replica_hostname*-relay-bin。如果不可能,请将现有复制品的中继日志索引文件复制到新的复制品,并将新的复制品上的relay_log_index系统变量设置为与现有复制品上使用的相匹配。如果在现有复制品上未显式设置此选项,请使用*existing_replica_hostname*-relay-bin.index。或者,如果您在按照本节中的其余步骤后已尝试启动新的复制品并遇到类似先前描述的错误,则执行以下步骤:

    1. 如果您尚未这样做,请在新的复制品上发出STOP REPLICA

      如果您已经重新启动了现有的复制品,请在现有的复制品上也发出STOP REPLICA

    2. 将现有复制品的中继日志索引文件的内容复制到新复制品的中继日志索引文件中,确保覆盖文件中已有的任何内容。

    3. 继续执行本节中的其余步骤。

  4. 复制完成后,重新启动现有复制品。

  5. 在新的复制品上,编辑配置并为新的复制品分配一个不被源或任何现有复制品使用的唯一服务器 ID(使用server_id系统变量)。

  6. 启动新的复制服务器,确保通过指定--skip-slave-start选项或从 MySQL 8.0.24 开始,使用skip_slave_start系统变量,确保复制尚未开始。使用性能模式复制表或发出SHOW REPLICA STATUS来确认新的复制品与现有复制品相比是否具有正确的设置。还要显示服务器 ID 和服务器 UUID,并验证这些对于新的复制品是正确且唯一的。

  7. 通过发出START REPLICA语句来启动复制线程。新的复制品现在使用其连接元数据存储库中的信息来启动复制过程。

19.1.3 具有全局事务标识符的复制

原文:dev.mysql.com/doc/refman/8.0/en/replication-gtids.html

19.1.3.1 GTID 格式和存储

19.1.3.2 GTID 生命周期

19.1.3.3 GTID 自动定位

19.1.3.4 使用 GTID 设置复制

19.1.3.5 使用 GTID 进行故障切换和扩展

19.1.3.6 从没有 GTID 的源复制到具有 GTID 的副本

19.1.3.7 GTID 复制限制

19.1.3.8 用于操作 GTID 的存储函数示例

本节解释了使用全局事务标识符(GTID)进行基于事务的复制。使用 GTID 时,每个事务都可以在原始服务器上提交时进行标识和跟踪,并由任何副本应用;这意味着在使用 GTID 时,不需要在启动新副本或故障切换到新源时引用日志文件或文件内的位置,这极大地简化了这些任务。由于基于 GTID 的复制完全基于事务,因此很容易确定源和副本是否一致;只要在源上提交的所有事务也在副本上提交,就可以保证两者之间的一致性。您可以使用基于语句或基于行的复制与 GTID(参见第 19.2.1 节,“复制格式”);但是,为了获得最佳结果,我们建议您使用基于行的格式。

GTID 在源和副本之间始终保留。这意味着您始终可以通过检查其二进制日志来确定任何副本上应用的任何事务的源。此外,一旦在给定服务器上提交具有特定 GTID 的事务,该服务器将忽略具有相同 GTID 的任何后续事务。因此,在源上提交的事务在副本上最多只能应用一次,这有助于保证一致性。

本节讨论以下主题:

  • GTID 的定义和创建方式,以及它们在 MySQL 服务器中的表示方式(参见第 19.1.3.1 节,“GTID 格式和存储”)。

  • GTID 的生命周期(参见第 19.1.3.2 节,“GTID 生命周期”)。

  • 用于同步使用 GTID 的副本和源的自动定位功能(参见第 19.1.3.3 节,“GTID 自动定位”)。

  • 设置和启动基于 GTID 的复制的一般流程(参见第 19.1.3.4 节,“使用 GTIDs 设置复制”)。

  • 在使用 GTIDs 时为新复制服务器提供建议的方法(参见第 19.1.3.5 节,“在故障转移和扩展中使用 GTIDs”)。

  • 使用 GTID-based 复制时应注意的限制和限制(参见第 19.1.3.7 节,“使用 GTIDs 进行复制的限制”)。

  • 存储函数可用于处理 GTIDs(参见第 19.1.3.8 节,“用于操作 GTIDs 的存储函数示例”)。

有关与 GTID-based 复制相关的 MySQL 服务器选项和变量的信息,请参见第 19.1.6.5 节,“全局事务 ID 系统变量”。另请参阅第 14.18.2 节,“与全局事务标识符(GTIDs)一起使用的函数”"),其中描述了 MySQL 8.0 支持用于 GTIDs 的 SQL 函数。

原文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-concepts.html

19.1.3.1 GTID 格式和存储

全局事务标识符(GTID)是在源服务器上(源)提交的每个事务创建并关联的唯一标识符。该标识符不仅对于其起源的服务器是唯一的,而且在给定复制拓扑结构中的所有服务器上都是唯一的。

GTID 分配区分了客户端事务(在源上提交)和复制事务(在副本上重现)。当客户端事务在源上提交时,如果事务已写入二进制日志,则会分配一个新的 GTID。客户端事务保证具有单调递增的 GTID,生成的数字之间没有间隙。如果客户端事务未写入二进制日志(例如,因为事务被过滤掉,或者事务是只读的),则在源服务器上不会分配 GTID。

复制事务保留在源服务器上分配给事务的相同 GTID。GTID 在复制事务开始执行之前存在,并且即使在副本上未将复制事务写入二进制日志或在副本上被过滤掉,也会持久存在。MySQL 系统表 mysql.gtid_executed 用于保留应用于 MySQL 服务器上的所有事务的分配 GTID,除了那些存储在当前活动二进制日志文件中的事务。

GTID 的自动跳过功能意味着在源上提交的事务在副本上最多只能应用一次,这有助于保证一致性。一旦具有特定 GTID 的事务在给定服务器上提交,那么该服务器将忽略执行具有相同 GTID 的后续事务的任何尝试。不会引发错误,也不会执行事务中的任何语句。

如果具有特定 GTID 的事务已经在服务器上开始执行,但尚未提交或回滚,则在服务器上尝试启动具有相同 GTID 的并发事务会被阻塞。服务器既不开始执行并发事务,也不将控制权返回给客户端。一旦第一次尝试的事务提交或回滚,那些在相同 GTID 上阻塞的并发会话可以继续。如果第一次尝试回滚,一个并发会话将继续尝试事务,而任何其他在相同 GTID 上阻塞的并发会话将保持阻塞。如果第一次尝试提交,所有并发会话将停止被阻塞,并自动跳过事务的所有语句。

GTID 表示为一对坐标,用冒号字符(:)分隔,如下所示:

GTID = *source_id*:*transaction_id*

source_id 标识了来源服务器。通常,使用源的 server_uuid 来实现此目的。transaction_id 是由事务在源上提交的顺序确定的序列号。例如,第一个提交的事务的 transaction_id1,在同一来源服务器上提交的第十个事务被分配一个 transaction_id10。在 GTID 中,事务不可能具有 0 作为序列号。例如,在具有 UUID 3E11FA47-71CA-11E1-9E33-C80AA9429562 的服务器上最初提交的第二十三个事务具有以下 GTID:

3E11FA47-71CA-11E1-9E33-C80AA9429562:23

服务器实例上 GTID 的序列号上限是有符号 64 位整数的非负值数量(2 的 63 次方减 1,即 9,223,372,036,854,775,807)。如果服务器用尽了 GTID,将执行 binlog_error_action 中指定的操作。从 MySQL 8.0.23 开始,当服务器实例接近限制时会发出警告消息。

事务的 GTID 在 mysqlbinlog 的输出中显示,并用于在性能模式复制状态表中标识单个事务,例如 replication_applier_status_by_workergtid_next 系统变量 (@@GLOBAL.gtid_next) 存储的是单个 GTID。

GTID 集合

一个 GTID 集合由一个或多个单个 GTID 或 GTID 范围组成。在 MySQL 服务器中,GTID 集合有多种用途。例如,gtid_executedgtid_purged 系统变量存储的值就是 GTID 集合。START REPLICA(或 MySQL 8.0.22 之前的 START SLAVE)子句 UNTIL SQL_BEFORE_GTIDSUNTIL SQL_AFTER_GTIDS 可以用来使复制进程仅处理 GTID 集合中第一个 GTID 之前的事务,或在 GTID 集合中最后一个 GTID 之后停止。内置函数 GTID_SUBSET()GTID_SUBTRACT() 需要 GTID 集合作为输入。

来自同一服务器的一系列 GTID 可以合并为一个表达式,如下所示:

3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5

上述示例代表了在 MySQL 服务器上起源的第一到第五个事务,其server_uuid3E11FA47-71CA-11E1-9E33-C80AA9429562。来自同一服务器的多个单个 GTID 或 GTID 范围也可以包含在单个表达式中,GTID 或范围之间用冒号分隔,如下例所示:

3E11FA47-71CA-11E1-9E33-C80AA9429562:1-3:11:47-49

GTID 集可以包含任意组合的单个 GTID 和 GTID 范围,并且可以包含来自不同服务器的 GTID。此示例显示了存储在副本的gtid_executed系统变量(@@GLOBAL.gtid_executed)中的 GTID 集,该副本已应用来自多个来源的事务:

2174B383-5441-11E8-B90A-C80AA9429562:1-3, 24DA167-0C0C-11E8-8442-00059A3C7B00:1-19

当从服务器变量返回 GTID 集时,UUID 按字母顺序排列,数字间隔被合并并按升序排列。

GTID 集的语法如下:

*gtid_set*:
    *uuid_set* [, *uuid_set*] ...
    | ''

*uuid_set*:
    *uuid*:*interval*[:*interval*]...

*uuid*:
    *hhhhhhhh*-*hhhh*-*hhhh*-*hhhh*-*hhhhhhhhhhhh*

*h*:
    [0-9|A-F]

*interval*:
    *n*[-*n*]

    (*n* >= 1)
mysql.gtid_executed 表

GTIDs 存储在名为gtid_executed的表中,位于mysql数据库中。此表中的一行包含每个 GTID 或其代表的 GTID 集的起始服务器的 UUID,以及集合的起始和结束事务 ID;对于仅引用单个 GTID 的行,这两个值相同。

当安装或升级 MySQL 服务器时,将创建(如果尚不存在)mysql.gtid_executed表,使用类似于以下所示的CREATE TABLE语句:

CREATE TABLE gtid_executed (
    source_uuid CHAR(36) NOT NULL,
    interval_start BIGINT(20) NOT NULL,
    interval_end BIGINT(20) NOT NULL,
    PRIMARY KEY (source_uuid, interval_start)
)

警告

与其他 MySQL 系统表一样,请不要尝试自行创建或修改此表。

mysql.gtid_executed表供 MySQL 服务器内部使用。当在副本上禁用二进制日志记录时,它使副本能够使用 GTIDs,并在二进制日志丢失时保留 GTID 状态。请注意,如果发出RESET MASTER命令,mysql.gtid_executed表将被清除。

仅当gtid_modeONON_PERMISSIVE时,GTIDs 才存储在mysql.gtid_executed表中。如果二进制日志记录已禁用(log_binOFF),或者如果log_replica_updateslog_slave_updates已禁用,则服务器将每个事务的 GTID 与事务一起存储在缓冲区中提交事务时,并且后台线程定期将缓冲区的内容作为一个或多个条目添加到mysql.gtid_executed表中。此外,表会定期以用户可配置的速率进行压缩,如 mysql.gtid_executed 表压缩中所述。

如果启用了二进制日志记录(log_binON),从 MySQL 8.0.17 开始,仅适用于InnoDB存储引擎,服务器会在事务提交时以与禁用二进制日志记录或复制更新日志相同的方式更新mysql.gtid_executed表,存储每个事务的 GTID。然而,在 MySQL 8.0.17 之前的版本中,以及对于其他存储引擎,服务器仅在二进制日志轮换或服务器关闭时更新mysql.gtid_executed表。在这些时候,服务器会将之前二进制日志中写入的所有事务的 GTID 写入mysql.gtid_executed表。这种情况适用于 MySQL 8.0.17 之前的源端,或者在启用二进制日志记录的 MySQL 8.0.17 之前的复制端,或者使用除InnoDB之外的存储引擎,它具有以下后果:

  • 在服务器意外停止的情况下,当前二进制日志文件中的 GTID 集合不会保存在mysql.gtid_executed表中。这些 GTID 在恢复过程中从二进制日志文件中添加到表中,以便复制可以继续进行。唯一的例外是,如果在服务器重新启动时禁用了二进制日志记录(使用--skip-log-bin--disable-log-bin)。在这种情况下,服务器无法访问二进制日志文件以恢复 GTID,因此无法启动复制。

  • mysql.gtid_executed表不包含所有已执行事务的 GTID 的完整记录。这些信息由全局值gtid_executed系统变量提供。在 MySQL 8.0.17 之前的版本和使用除InnoDB之外的存储引擎时,始终使用@@GLOBAL.gtid_executed,该值在每次提交后更新,以表示 MySQL 服务器的 GTID 状态,而不是查询mysql.gtid_executed表。

MySQL 服务器在只读或超级只读模式下仍可以写入mysql.gtid_executed表。在 MySQL 8.0.17 之前的版本中,这确保了在这些模式下仍然可以旋转二进制日志文件。如果无法访问mysql.gtid_executed表进行写入,并且二进制日志文件因其他原因而旋转(而不是达到最大文件大小max_binlog_size),则继续使用当前的二进制日志文件。向请求旋转的客户端返回错误消息,并在服务器上记录警告。如果无法访问mysql.gtid_executed表进行写入,并且达到max_binlog_size,则服务器根据其binlog_error_action设置做出响应。如果设置为IGNORE_ERROR,则在服务器上记录错误并停止二进制日志记录,或者如果设置为ABORT_SERVER,则服务器关闭。

mysql.gtid_executed 表压缩

随着时间的推移,mysql.gtid_executed表可能会填满许多行,这些行引用在同一服务器上起源的单个 GTID,并且其事务 ID 组成一个范围,类似于这里显示的内容:

+--------------------------------------+----------------+--------------+
| source_uuid                          | interval_start | interval_end |
|--------------------------------------+----------------+--------------|
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37             | 37           |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 38             | 38           |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 39             | 39           |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 40             | 40           |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 41             | 41           |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 42             | 42           |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 43             | 43           |
...

为节省空间,MySQL 服务器可以定期压缩mysql.gtid_executed表,通过用跨越整个事务标识符间隔的单行替换每个这样的行集,如下所示:

+--------------------------------------+----------------+--------------+
| source_uuid                          | interval_start | interval_end |
|--------------------------------------+----------------+--------------|
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37             | 43           |
...

服务器可以使用名为thread/sql/compress_gtid_table的专用前台线程执行压缩。此线程不在SHOW PROCESSLIST的输出中列出,但可以在threads表中查看,如下所示:

mysql> SELECT * FROM performance_schema.threads WHERE NAME LIKE '%gtid%'\G
*************************** 1\. row ***************************
          THREAD_ID: 26
               NAME: thread/sql/compress_gtid_table
               TYPE: FOREGROUND
     PROCESSLIST_ID: 1
   PROCESSLIST_USER: NULL
   PROCESSLIST_HOST: NULL
     PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Daemon
   PROCESSLIST_TIME: 1509
  PROCESSLIST_STATE: Suspending
   PROCESSLIST_INFO: NULL
   PARENT_THREAD_ID: 1
               ROLE: NULL
       INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: NULL
       THREAD_OS_ID: 18677

当服务器启用二进制日志记录时,不使用此压缩方法,而是在每次二进制日志旋转时压缩mysql.gtid_executed表。但是,当服务器禁用二进制日志记录时,thread/sql/compress_gtid_table线程会休眠,直到执行了指定数量的事务,然后唤醒以压缩mysql.gtid_executed表。然后再休眠,直到发生相同数量的事务,然后再次唤醒以执行压缩,无限循环。在表被压缩之前经过的事务数量,因此压缩速率,由gtid_executed_compression_period系统变量的值控制。将该值设置为 0 意味着线程永远不会唤醒,这意味着不使用此显式压缩方法。相反,根据需要隐式进行压缩。

从 MySQL 8.0.17 开始,InnoDB 事务由一个独立进程写入到mysql.gtid_executed表,与非InnoDB事务分开。这个进程由不同的线程innodb/clone_gtid_thread控制。这个 GTID 持久化线程将 GTID 分组收集,将它们刷新到mysql.gtid_executed表,然后压缩表格。如果服务器同时有InnoDB事务和非InnoDB事务,它们分别写入到mysql.gtid_executed表,那么compress_gtid_table线程执行的压缩会干扰 GTID 持久化线程的工作,并且可能显著减慢速度。因此,从那个版本开始,建议将gtid_executed_compression_period设置为 0,这样compress_gtid_table线程就永远不会被激活。

从 MySQL 8.0.23 开始,gtid_executed_compression_period的默认值为 0,InnoDB和非InnoDB事务都由 GTID 持久化线程写入到mysql.gtid_executed表。

对于 MySQL 8.0.17 之前的版本,默认值为 1000 的gtid_executed_compression_period可以使用,意味着每 1000 个事务后对表进行压缩,或者您可以选择另一个值。在这些版本中,如果将值设置为 0 且禁用了二进制日志记录,则不会对mysql.gtid_executed表执行显式压缩,如果这样做,您应该准备好表可能需要的磁盘空间可能会大幅增加。

当启动服务器实例时,如果gtid_executed_compression_period设置为非零值并且启动了thread/sql/compress_gtid_table线程,在大多数服务器配置中,将为mysql.gtid_executed表执行显式压缩。在 MySQL 8.0.17 之前的版本中,启用二进制日志时,压缩是由于启动时二进制日志轮换触发的。在 MySQL 8.0.20 之后的版本中,压缩是由线程启动触发的。在这些版本之间的版本中,启动时不会进行压缩。

译文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-lifecycle.html

19.1.3.2 GTID 生命周期

GTID 的生命周期包括以下步骤:

  1. 事务在源端执行并提交。此客户端事务被分配一个由源的 UUID 和尚未在此服务器上使用的最小非零事务序列号组成的 GTID。GTID 被写入源的二进制日志(在日志中的事务之前立即写入)。如果客户端事务未写入二进制日志(例如,因为事务被过滤掉,或者事务是只读的),则不会分配 GTID。

  2. 如果为事务分配了 GTID,则在提交时通过将其写入二进制日志的方式原子地持久化该 GTID(作为 Gtid_log_event)。每当二进制日志被轮换或服务器关闭时,服务器将为写入到上一个二进制日志文件中的所有事务写入 GTID 到 mysql.gtid_executed 表中。

  3. 如果为事务分配了 GTID,则在事务提交后不久通过将其添加到 gtid_executed 系统变量 (@@GLOBAL.gtid_executed) 中的 GTID 集合来非原子化地外部化该 GTID。此 GTID 集合包含所有已提交 GTID 事务的表示,并且在复制中用作表示服务器状态的令牌。启用二进制日志记录(源端所需)后,gtid_executed 系统变量中的 GTID 集合是应用的所有事务的完整记录,但 mysql.gtid_executed 表不是,因为最近的历史仍在当前二进制日志文件中。

  4. 在二进制日志数据传输到副本并存储在副本的中继日志中(使用已建立的机制进行此过程,详见第 19.2 节,“复制实现”),副本读取 GTID 并将其设置为其 gtid_next 系统变量的值。这告诉副本下一个事务必须使用此 GTID 记录。重要的是要注意,副本在会话上下文中设置 gtid_next

  5. 副本验证尚未有任何线程拥有gtid_next中的 GTID 以处理事务。通过首先读取和检查复制的事务的 GTID,然后再处理事务本身,副本确保不仅在副本上未应用具有此 GTID 的先前事务,而且也没有其他会话已经读取此 GTID 但尚未提交关联事务。因此,如果多个客户端尝试并发应用相同的事务,服务器通过只允许其中一个执行来解决此问题。副本的gtid_owned系统变量(@@GLOBAL.gtid_owned)显示当前正在使用的每个 GTID 及拥有它的线程的 ID。如果 GTID 已经被使用,不会引发错误,并且自动跳过功能用于忽略该事务。

  6. 如果 GTID 尚未被使用,副本将应用复制的事务。因为gtid_next已设置为源已分配的 GTID,副本不会尝试为此事务生成新的 GTID,而是使用存储在gtid_next中的 GTID。

  7. 如果副本上启用了二进制日志记录,GTID 将在提交时以原子方式持久化,通过在事务开始时将其写入二进制日志(作为Gtid_log_event)。每当二进制日志轮换或服务器关闭时,服务器将为之前写入的所有事务写入的 GTID 写入mysql.gtid_executed表。

  8. 如果副本上禁用了二进制日志记录,则通过直接将其写入mysql.gtid_executed表来以原子方式持久化 GTID。MySQL 会向事务追加一个语句,将 GTID 插入表中。从 MySQL 8.0 开始,对于 DDL 语句以及 DML 语句,此操作都是原子的。在这种情况下,mysql.gtid_executed表是副本上应用的事务的完整记录。

  9. 在副本上提交的事务后不久,GTID 将通过将其添加到副本的gtid_executed系统变量(@@GLOBAL.gtid_executed)中的 GTID 集合中非原子化地外部化。对于源,此 GTID 集合包含所有已提交 GTID 事务集合的表示。如果副本上禁用了二进制日志记录,则mysql.gtid_executed表也是副本上应用的事务的完整记录。如果副本上启用了二进制日志记录,意味着某些 GTID 仅记录在二进制日志中,则gtid_executed系统变量中的 GTID 集合是唯一的完整记录。

在源端完全被过滤掉的客户端事务不会被分配 GTID,因此它们不会被添加到gtid_executed系统变量的事务集合中,也不会被添加到mysql.gtid_executed表中。然而,在副本上完全被过滤掉的复制事务的 GTID 会被保留。如果在副本上启用了二进制日志记录,被过滤掉的事务会被写入二进制日志作为一个Gtid_log_event,然后是一个只包含BEGINCOMMIT语句的空事务。如果禁用了二进制日志记录,被过滤掉的事务的 GTID 会被写入mysql.gtid_executed表中。保留被过滤掉事务的 GTID 确保了mysql.gtid_executed表和gtid_executed系统变量中的 GTID 集合可以被压缩。它还确保了如果副本重新连接到源端,被过滤掉的事务不会再次被检索,如第 19.1.3.3 节“GTID 自动定位”中所解释的那样。

在多线程副本(具有replica_parallel_workers > 0slave_parallel_workers > 0)上,事务可以并行应用,因此复制事务可以无序提交(除非设置了replica_preserve_commit_order=1slave_preserve_commit_order=1)。当发生这种情况时,gtid_executed系统变量中的 GTID 集合包含多个 GTID 范围之间的间隙。(在源端或单线程副本上,GTID 是单调递增的,数字之间没有间隙。)多线程副本上的间隙仅出现在最近应用的事务之间,并且随着复制的进行而填补。当使用STOP REPLICA语句干净地停止复制线程时,正在进行的事务会被应用,以便填补间隙。在发生诸如服务器故障或使用KILL语句停止复制线程等关闭事件时,这些间隙可能会保留。

哪些更改会被分配一个 GTID?

典型情况是服务器为已提交的事务生成一个新的 GTID。然而,除了事务之外,GTIDs 也可以分配给其他更改,并且在某些情况下,单个事务可以被分配多个 GTIDs。

每个写入二进制日志的数据库更改(DDL 或 DML)都被分配一个 GTID。这包括自动提交的更改,以及使用BEGINCOMMITSTART TRANSACTION语句提交的更改。GTID 也分配给数据库的创建、修改或删除,以及非表数据库对象(如存储过程、函数、触发器、事件、视图、用户、角色或授权)。

非事务更新以及事务更新都被分配 GTID。此外,对于非事务更新,如果在尝试写入二进制日志缓存时发生磁盘写入失败,从而在二进制日志中创建了一个间隙,那么生成的事件日志事件将被分配一个 GTID。

当一个表被二进制日志中的生成语句自动删除时,该语句被分配一个 GTID。当一个复制开始应用来自刚刚启动的源的事件时,临时表会被自动删除,并且当使用基于语句的复制(binlog_format=STATEMENT)并且一个具有打开临时表的用户会话断开连接时。使用MEMORY存储引擎的表在服务器启动后第一次访问时会自动删除,因为在关闭期间可能会丢失行。

当一个事务在原始服务器上没有写入二进制日志时,服务器不会为其分配 GTID。这包括被回滚的事务和在原始服务器上禁用二进制日志记录时执行的事务,无论是全局禁用(在服务器配置中指定--skip-log-bin)还是对会话禁用(SET @@SESSION.sql_log_bin = 0)。当使用基于行的复制时(binlog_format=ROW),这也包括无操作事务。

XA 事务为事务的XA PREPARE阶段和XA COMMITXA ROLLBACK阶段分配单独的 GTID。XA 事务被持久准备,以便用户在失败的情况下(在复制拓扑中可能包括故障转移到另一台服务器)提交或回滚它们。因此,事务的两个部分被分别复制,因此它们必须有自己的 GTID,即使一个被回滚的非 XA 事务不会有 GTID。

在以下特殊情况下,单个语句可以生成多个事务,因此被分配多个 GTID:

  • 调用了提交多个事务的存储过程。为存储过程提交的每个事务生成一个 GTID。

  • 一个多表DROP TABLE语句会删除不同类型的表。如果任何表使用不支持原子 DDL 的存储引擎,或者任何表是临时表,可能会生成多个 GTID。

  • 当使用基于行的复制(binlog_format=ROW)时,会发出CREATE TABLE ... SELECT语句。为CREATE TABLE操作生成一个 GTID,并为行插入操作生成一个 GTID。

gtid_next系统变量

默认情况下,在用户会话中提交的新事务,服务器会自动生成并分配新的 GTID。在副本上应用事务时,会保留来自原始服务器的 GTID。您可以通过设置gtid_next系统变量的会话值来更改此行为:

  • gtid_next设置为AUTOMATIC时,这是默认值,事务提交并写入二进制日志时,服务器会自动生成并分配新的 GTID。如果事务回滚或由于其他原因未写入二进制日志,则服务器不会生成和分配 GTID。

  • 如果将gtid_next设置为有效的 GTID(由 UUID 和事务序列号组成,用冒号分隔),服务器会将该 GTID 分配给您的事务。即使事务未写入二进制日志,或者事务为空,此 GTID 也会被分配并添加到gtid_executed

请注意,在将gtid_next设置为特定 GTID 后,事务已提交或回滚后,必须在任何其他语句之前发出显式的SET @@SESSION.gtid_next语句。如果不想显式分配更多 GTID,则可以使用此方法将 GTID 值设置回AUTOMATIC

当复制应用程序线程应用复制事务时,它们使用这种技术,将@@SESSION.gtid_next显式设置为在原始服务器上分配的复制事务的 GTID。这意味着来自原始服务器的 GTID 被保留,而不是由副本生成和分配新的 GTID。这也意味着即使在副本上禁用了二进制日志记录或副本更新日志,或者事务是无操作或在副本上被过滤掉,GTID 也会被添加到gtid_executed

客户端可以通过将@@SESSION.gtid_next设置为特定的 GTID 来模拟一个复制事务,然后执行该事务。这种技术被mysqlbinlog用于生成客户端可以重放以保留 GTID 的二进制日志转储。通过客户端提交的模拟复制事务与通过复制应用程序线程提交的复制事务完全等效,在事后无法区分它们。

gtid_purged系统变量

gtid_purged系统变量(@@GLOBAL.gtid_purged)中包含了在服务器上已提交但不存在于服务器上任何二进制日志文件中的所有事务的 GTID。gtid_purgedgtid_executed的子集。gtid_purged中包含以下类别的 GTID:

  • 在副本上禁用二进制日志记录的复制事务的 GTID。

  • 被写入二进制日志文件并已被清除的事务的 GTID。

  • 通过语句SET @@GLOBAL.gtid_purged显式添加到集合中的 GTID。

您可以更改gtid_purged的值,以记录在服务器上已应用某个 GTID 集的事务,尽管这些事务在服务器上的任何二进制日志中都不存在。当您将 GTID 添加到gtid_purged时,它们也会被添加到gtid_executed中。执行此操作的一个示例用例是,当您在服务器上恢复一个或多个数据库的备份时,但您没有包含服务器上事务的相关二进制日志。在 MySQL 8.0 之前,只有在gtid_executed(因此也是gtid_purged)为空时才能更改gtid_purged的值。从 MySQL 8.0 开始,不再有此限制,您还可以选择是否用指定的 GTID 集替换gtid_purged中的整个 GTID 集,或者将指定的 GTID 集添加到已在gtid_purged中的 GTID 中。有关如何执行此操作的详细信息,请参阅gtid_purged的描述。

当服务器启动时,gtid_executedgtid_purged 系统变量中的 GTID 集合在初始化时被初始化。每个二进制日志文件都以事件Previous_gtids_log_event开头,其中包含了所有先前二进制日志文件中的 GTIDs 集合(由前一个文件的Previous_gtids_log_event中的 GTIDs 和前一个文件中每个Gtid_log_event的 GTIDs 组成)。最老和最近的二进制日志文件中的Previous_gtids_log_event的内容用于计算服务器启动时的gtid_executedgtid_purged 集合:

  • gtid_executed 是由最近的二进制日志文件中的Previous_gtids_log_event中的 GTIDs、该二进制日志文件中的事务的 GTIDs 以及mysql.gtid_executed表中存储的 GTIDs 的并集计算而得。这个 GTID 集合包含了服务器上已经使用过的 GTIDs(或者明确添加到gtid_purged中的 GTIDs),无论它们当前是否在服务器上的二进制日志文件中。它不包括当前在服务器上处理的事务的 GTIDs(@@GLOBAL.gtid_owned)。

  • gtid_purged 首先通过将最近的二进制日志文件中的Previous_gtids_log_event中的 GTIDs 和该二进制日志文件中的事务的 GTIDs 相加来计算。这一步给出了当前或曾经在服务器上的二进制日志中记录的 GTIDs 集合(gtids_in_binlog)。接下来,从最老的二进制日志文件中的Previous_gtids_log_event中减去gtids_in_binlog中的 GTIDs。这一步给出了当前在服务器上的二进制日志中记录的 GTIDs 集合(gtids_in_binlog_not_purged)。最后,从gtid_executed中减去gtids_in_binlog_not_purged。结果是在服务器上已经使用过的 GTIDs 集合,但当前没有在服务器上的二进制日志文件中记录,这个结果用于初始化gtid_purged

如果涉及来自 MySQL 5.7.7 或更早版本的二进制日志在这些计算中,可能会计算出gtid_executedgtid_purged的不正确 GTID 集,并且即使稍后重新启动服务器,它们仍然不正确。有关详细信息,请参阅binlog_gtid_simple_recovery系统变量的描述,该变量控制如何迭代二进制日志以计算 GTID 集。如果服务器上适用于其中描述的情况之一,请在启动服务器之前在服务器的配置文件中设置binlog_gtid_simple_recovery=FALSE。该设置使服务器迭代所有二进制日志文件(而不仅仅是最新和最旧的)以查找 GTID 事件开始出现的位置。如果服务器有大量没有 GTID 事件的二进制日志文件,这个过程可能需要很长时间。

重置 GTID 执行历史

如果需要在服务器上重置 GTID 执行历史,请使用RESET MASTER语句。例如,在新的 GTID 启用服务器上执行测试查询以验证复制设置,或者当您想要将新服务器加入到复制组中但它包含一些不被组复制接受的不需要的本地事务时,可能需要执行此操作。

警告

谨慎使用RESET MASTER,以避免丢失任何需要的 GTID 执行���史和二进制日志文件。

在执行RESET MASTER之前,请确保已备份服务器的二进制日志文件和二进制日志索引文件(如果有),并获取并保存gtid_executed系统变量的全局值中保存的 GTID 集(例如,通过执行SELECT @@GLOBAL.gtid_executed语句并保存结果)。如果要从该 GTID 集中删除不需要的事务,请使用mysqlbinlog检查事务的内容,以确保它们没有价值,不包含必须保存或复制的数据,并且不会导致服务器上的数据更改。

当您执行RESET MASTER时,将执行以下重置操作:

  • gtid_purged系统变量的值被设置为空字符串('')。

  • 全局值(但不是会话值)的gtid_executed系统变量被设置为空字符串。

  • mysql.gtid_executed 表被清空(参见 mysql.gtid_executed Table)。

  • 如果服务器启用了二进制日志记录,则现有的二进制日志文件将被删除,二进制日志索引文件将被清空。

请注意,RESET MASTER 是重置 GTID 执行历史记录的方法,即使服务器是一个禁用二进制日志记录的副本。RESET REPLICA 对 GTID 执行历史记录没有影响。

原文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-auto-positioning.html

19.1.3.3 GTID 自动定位

GTID 取代了以前需要确定源和副本之间数据流开始、停止或恢复点的文件偏移对。当使用 GTID 时,副本与源同步所需的所有信息都直接从复制数据流中获取。

要使用基于 GTID 的复制启动副本,需要在 CHANGE REPLICATION SOURCE TO 语句(从 MySQL 8.0.23 开始)或 CHANGE MASTER TO 语句(MySQL 8.0.23 之前)中启用 SOURCE_AUTO_POSITION | MASTER_AUTO_POSITION 选项。另外的 SOURCE_LOG_FILE | MASTER_LOG_FILESOURCE_LOG_POS | MASTER_LOG_POS 选项指定了日志文件的名称和文件内的起始位置,但是使用 GTID 时,副本不需要这些非本地数据。有关使用基于 GTID 的复制配置和启动源和副本的完整说明,请参见 Section 19.1.3.4, “Setting Up Replication Using GTIDs”。

SOURCE_AUTO_POSITION | MASTER_AUTO_POSITION 选项默认情况下是禁用的。如果在副本上启用了多源复制,则需要为每个适用的复制通道设置该选项。再次禁用 SOURCE_AUTO_POSITION | MASTER_AUTO_POSITION 选项会导致副本恢复到基于位置的复制;这意味着当 GTID_ONLY=ON 时,某些位置可能被标记为无效,在这种情况下,当禁用 SOURCE_AUTO_POSITION | MASTER_AUTO_POSITION 时,还必须同时指定 SOURCE_LOG_FILE | MASTER_LOG_FILESOURCE_LOG_POS | MASTER_LOG_POS

当副本启用了 GTIDs(GTID_MODE=ONON_PERMISSIVEOFF_PERMISSIVE)并启用了MASTER_AUTO_POSITION选项时,自动定位将被激活以连接到源端。源端必须设置GTID_MODE=ON才能成功连接。在初始握手中,副本发送一个包含其已经接收、提交或两者都有的交易的 GTID 集合。这个 GTID 集合等于gtid_executed系统变量(@@GLOBAL.gtid_executed)中的 GTID 集合和性能模式中记录的 GTID 集合的并集,性能模式中的 GTID 集合是作为已接收交易记录的(执行SELECT RECEIVED_TRANSACTION_SET FROM PERFORMANCE_SCHEMA.replication_connection_status语句的结果)。

源端通过发送其二进制日志中记录的所有交易来响应,这些交易的 GTID 不包含在副本发送的 GTID 集合中。为此,源端首先通过检查其二进制日志文件的头部中的Previous_gtids_log_event来确定要开始处理的适当二进制日志文件,从最近的文件开始检查。当源端找到第一个不包含副本缺失交易的Previous_gtids_log_event时,它就从那个二进制日志文件开始。这种方法是高效的,只有在副本落后源端很多个二进制日志文件时才会花费大量时间。然后,源端读取该二进制日志文件和后续文件中的交易,直到当前文件,发送副本缺失的带有 GTID 的交易,并跳过副本发送的 GTID 集合中的交易。副本接收到第一个缺失交易的经过时间取决于其在二进制日志文件中的偏移量。这种交换确保源端只发送副本尚未接收或提交的带有 GTID 的交易。如果副本从多个源接收交易,如钻石拓扑结构的情况下,自动跳过功能确保交易不会被应用两次。

如果应该由源发送的任何事务已经从源的二进制日志中清除,或者通过其他方法添加到gtid_purged系统变量的 GTID 集合中,源会向副本发送错误ER_MASTER_HAS_PURGED_REQUIRED_GTIDS,并且复制不会启动。缺失的已清除事务的 GTID 将在源的错误日志中被识别并列在警告消息ER_FOUND_MISSING_GTIDS中。副本无法自动从此错误中恢复,因为需要追赶源的事务历史的部分已被清除。尝试重新连接而没有启用MASTER_AUTO_POSITION选项只会导致副本上的已清除事务的丢失。从这种情况中恢复的正确方法是让副本从另一个源复制ER_FOUND_MISSING_GTIDS消息中列出的缺失事务,或者让副本被一个从更近期备份创建的新副本所取代。考虑修改源上的二进制日志过期时间(binlog_expire_logs_seconds)以确保不再发生这种情况。

如果在交换事务过程中发现复制品已经收到或提交了具有源 GTID 中 UUID 的事务,但源本身没有记录它们,源会向复制品发送错误ER_SLAVE_HAS_MORE_GTIDS_THAN_MASTER,复制不会开始。如果源没有设置sync_binlog=1并遇到断电或操作系统崩溃,且丢失了尚未同步到二进制日志文件的已提交事务,但已被复制品接收,那么就会出现这种情况。如果在源重新启动后有任何客户端提交事务,可能导致源和复制品使用相同的 GTID 进行不同的事务,源和复制品可能会发散。从这种情况中恢复的正确方法是手动检查源和复制品是否发散。如果现在对不同事务使用相同的 GTID,则需要根据需要对单个事务执行手动冲突解决,或者从复制拓扑中删除源或复制品。如果问题仅在源上缺少事务,则可以将源变为复制品,使其赶上复制拓扑中的其他服务器,然后根据需要再次将其变为源。

对于钻石拓扑结构中的多源复制(其中复制品从两个或更多源复制,这些源又从一个共同源复制),当使用基于 GTID 的复制时,请确保多源复制上的所有通道上的任何复制过滤器或其他通道配置都是相同的。使用基于 GTID 的复制时,过滤器仅应用于事务数据,而 GTID 不会被过滤掉。这是为了使复制品的 GTID 集与源保持一致,这意味着可以使用 GTID 自动定位而无需每次重新获取被过滤的事务。在下游复制品是多源的情况下,并且在钻石拓扑结构中从多个源接收相同事务的情况下,下游复制品现在具有事务的多个版本,结果取决于哪个通道首先应用该事务。尝试的第二个通道通过使用 GTID 自动跳过来跳过该事务,因为该事务的 GTID 已被第一个通道添加到gtid_executed集中。在通道上具有相同过滤器的情况下,没有问题,因为所有事务的所有版本都包含相同的数据,因此结果是相同的。然而,在通道上具有不同过滤器的情况下,数据库可能变得不一致,复制可能会挂起。

原文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-howto.html

19.1.3.4 使用 GTID 设置复制

本节描述了在 MySQL 8.0 中配置和启动基于 GTID 的复制的过程。这是一个“冷启动”过程,假设您要么是第一次启动源服务器,要么可以停止它;有关从运行中的源服务器使用 GTID 为副本提供服务的信息,请参阅第 19.1.3.5 节,“使用 GTID 进行故障转移和扩展”。有关在线更改服务器上的 GTID 模式的信息,请参阅第 19.1.4 节,“在线更改 GTID 模式”。

最简单的 GTID 复制拓扑结构的启动过程中的关键步骤,包括一个源和一个副本,如下所示:

  1. 如果复制已经在运行,请使两个服务器变为只读状态以进行同步。

  2. 停止两个服务器。

  3. 使用启用了 GTID 并配置了正确选项的正确选项重新启动两个服务器。

    启动服务器所需的mysqld选项将在本节稍后的示例中讨论。

  4. 指示副本使用源作为复制数据源并使用自动定位。完成此步骤所需的 SQL 语句在本节稍后的示例中描述。

  5. 进行新的备份。包含没有 GTID 的事务的二进制日志不能在启用 GTID 的服务器上使用,因此在此点之前进行的备份不能与新配置一起使用。

  6. 启动副本,然后在两个服务器上禁用只读模式,以便它们可以接受更新。

在以下示例中,两个服务器已经作为源和副本运行,使用 MySQL 的基于二进制日志位置的复制协议。如果您要使用新服务器,请参阅第 19.1.2.3 节,“为复制创建用户”以获取有关为复制连接添加特定用户的信息,以及第 19.1.2.1 节,“设置复制源配置”以获取有关设置server_id变量的信息。以下示例显示了如何在服务器的选项文件中存储mysqld启动选项,请参阅第 6.2.2.2 节,“使用选项文件”以获取更多信息。或者,您可以在运行mysqld时使用启动选项。

后续大部分步骤需要使用 MySQL root 帐户或具有SUPER权限的其他 MySQL 用户帐户。mysqladmin shutdown 需要SUPER权限或SHUTDOWN权限。

第一步:同步服务器。 仅在使用不使用 GTID 复制的服务器时才需要此步骤。对于新服务器,请继续到第三步。通过在每个服务器上将read_only系统变量设置为ON来使服务器只读,发出以下命令:

mysql> SET @@GLOBAL.read_only = ON;

等待所有正在进行的事务提交或回滚。然后,允许复制品赶上源。确保复制品处理了所有更新非常重要

如果您使用二进制日志来进行除了复制之外的任何操作,例如进行时点备份和恢复,请等到您不再需要包含没有 GTID 的旧二进制日志。理想情况下,等待服务器清除所有二进制日志,并等待任何现有备份过期。

重要提示

重要提示:必须了解不包含 GTID 的事务的日志不能在启用 GTID 的服务器上使用。在继续之前,您必须确保在拓扑结构中任何地方都不存在不带 GTID 的事务。

第二步:停止两个服务器。 使用mysqladmin停止每个服务器,如下所示,其中username是具有足够权限关闭服务器的 MySQL 用户的用户名:

$> mysqladmin -u*username* -p shutdown

然后在提示处提供此用户的密码。

第三步:启用两个启用 GTID 的服务器。 要启用基于 GTID 的复制,必须通过将gtid_mode变量设置为ON来启用每个服务器的 GTID 模式,并通过启用enforce_gtid_consistency变量来确保仅记录对于基于 GTID 的复制安全的语句。例如:

gtid_mode=ON
enforce-gtid-consistency=ON

使用 --skip-slave-start 选项或从 MySQL 8.0.24 开始,使用 skip_slave_start 系统变量,确保在配置副本设置之前不会启动复制。从 MySQL 8.0.26 开始,改用 --skip-replica-startskip_replica_start。有关 GTID 相关选项和变量的更多信息,请参见 第 19.1.6.5 节,“全局事务 ID 系统变量”。

在使用 mysql.gtid_executed 表 时,不需要启用二进制日志记录才能使用 GTIDs 是强制性的。源服务器必须始终启用二进制日志记录才能进行复制。但是,副本服务器可以使用 GTIDs,但不启用二进制日志记录。如果需要在副本服务器上禁用二进制日志记录,可以通过为副本指定 --skip-log-bin--log-replica-updates=OFF--log-slave-updates=OFF 选项来实现。

第 4 步:配置副本以使用基于 GTID 的自动定位。 告诉副本使用具有基于 GTID 的事务的源作为复制数据源,并使用基于 GTID 的自动定位而不是基于文件的定位。在副本上发出 CHANGE REPLICATION SOURCE TO 语句(从 MySQL 8.0.23 开始)或 CHANGE MASTER TO 语句(在 MySQL 8.0.23 之前),在语句中包含 SOURCE_AUTO_POSITION | MASTER_AUTO_POSITION 选项,告诉副本源的事务由 GTIDs 标识。

您可能还需要为源主机名和端口号以及用于副本连接到源的复制用户帐户的用户名和密码提供适当的值;如果这些值在第 1 步之前已经设置并且不需要进行进一步更改,则可以安全地从此处显示的语句中省略相应的选项。

mysql> CHANGE MASTER TO
     >     MASTER_HOST = *host*,
     >     MASTER_PORT = *port*,
     >     MASTER_USER = *user*,
     >     MASTER_PASSWORD = *password*,
     >     MASTER_AUTO_POSITION = 1;

Or from MySQL 8.0.23:

mysql> CHANGE REPLICATION SOURCE TO
     >     SOURCE_HOST = *host*,
     >     SOURCE_PORT = *port*,
     >     SOURCE_USER = *user*,
     >     SOURCE_PASSWORD = *password*,
     >     SOURCE_AUTO_POSITION = 1;

第 5 步:进行新的备份。 在启用 GTIDs 之前制作的现有备份现在无法在这些服务器上使用,因为您已经启用了 GTIDs。在这一点上进行新的备份,这样您就不会没有可用的备份了。

例如,您可以在执行备份的服务器上执行FLUSH LOGS。然后要么明确地进行备份,要么等待您设置的任何定期备份例程的下一次迭代。

步骤 6:启动副本并禁用只读模式。 像这样启动副本:

mysql> START SLAVE;
Or from MySQL 8.0.22:
mysql> START REPLICA;

如果您在第 1 步中将服务器配置为只读,则需要执行以下步骤才能使服务器再次接受更新。发出以下语句:

mysql> SET @@GLOBAL.read_only = OFF;

基于 GTID 的复制现在应该正在运行,您可以像以前一样开始(或恢复)源上的活动。第 19.1.3.5 节,“使用 GTIDs 进行故障转移和扩展”,讨论了在使用 GTIDs 时创建新副本。

译文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-failover.html

19.1.3.5 使用 GTIDs 进行故障切换和扩展

在使用带有全局事务标识符(GTIDs)的 MySQL 复制时,有许多技术可用于为新副本提供数据,然后用于扩展,必要时提升为源以进行故障切换。本节描述以下技术:

  • 简单复制

  • 将数据和事务复制到副本

  • 注入空事务

  • 排除具有 gtid_purged 的事务

  • 恢复 GTID 模式副本

全局事务标识符被添加到 MySQL 复制中,目的是简化复制数据流的管理以及特定情况下的故障切换活动。每个标识符唯一标识一组二进制日志事件,这些事件一起构成一个事务。GTIDs 在应用对数据库的更改中起着关键作用:服务器会自动跳过任何具有服务器识别为其之前已处理过的标识符的事务。这种行为对于自动复制定位和正确的故障切换至关重要。

标识符与构成给定事务的事件集之间的映射被记录在二进制日志中。当为新服务器提供来自另一个现有服务器的数据时,这会带来一些挑战。为了在新服务器上复制标识符集,需要将标识符从旧服务器复制到新服务器,并保留标识符与实际事件之间的关系。这对于恢复一个立即可用作故障切换或切换源的副本是必要的。

简单复制。 在新服务器上复制所有标识符和事务的最简单方法是将新服务器制作为具有完整执行历史记录的源的副本,并在两个服务器上启用全局事务标识符。有关更多信息,请参见 Section 19.1.3.4, “使用 GTIDs 设置复制”。

一旦复制开始,新服务器会从源服务器复制整个二进制日志,从而获取所有关于所有 GTIDs 的信息。

这种方法简单而有效,但需要副本从源读取二进制日志;新副本有时可能需要相对较长的时间才能赶上源,因此此方法不适用于快速故障转移或从备份中恢复。本节解释了如何通过将二进制日志文件复制到新服务器来避免从源获取所有执行历史记录。

将数据和事务复制到副本。 当源服务器之前处理了大量事务时,执行整个事务历史记录可能会耗时,这在设置新副本时可能会成为一个主要瓶颈。为了消除这一要求,可以将源服务器包含的数据集、二进制日志和全局事务信息的快照导入到新副本中。快照被拍摄的服务器可以是源服务器或其副本之一,但必须确保服务器在复制数据之前已处理了所有必需的事务。

有几种这种方法的变体,其区别在于从二进制日志中转移数据转储和事务到副本的方式,如下所述:

数据集

  1. 在源服务器上使用mysqldump创建一个转储文件。设置mysqldump选项--master-data(默认值为 1)以包含带有二进制日志信息的CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句。将--set-gtid-purged选项设置为AUTO(默认)或ON,以在转储中包含有关已执行事务的信息。然后使用mysql客户端在目标服务器上导入转储文件。

  2. 或者,使用原始数据文件在源服务器上创建数据快照,然后将这些文件复制到目标服务器,按照第 19.1.2.5 节,“选择数据快照方法”中的说明进行操作。如果使用InnoDB表,可以使用 MySQL Enterprise Backup 组件中的mysqlbackup命令生成一致的快照。该命令记录了与快照对应的日志名称和偏移量,以便在副本上使用。MySQL Enterprise Backup 是 MySQL Enterprise 订阅的一部分,是一款商业产品。详细信息请参见第 32.1 节,“MySQL Enterprise Backup 概述”。

  3. 或者,停止源服务器和目标服务器,将源数据目录的内容复制到新副本的数据目录,然后重新启动副本。如果使用此方法,副本必须配置为基于 GTID 的复制,换句话说,使用 gtid_mode=ON。有关此方法的说明和重要信息,请参见 第 19.1.2.8 节“将副本添加到复制环境”。

事务历史

如果源服务器在其二进制日志中具有完整的事务历史记录(即,GTID 集 @@GLOBAL.gtid_purged 为空),则可以使用这些方法。

  1. 使用 mysqlbinlog 将源服务器的二进制日志导入新副本,使用 --read-from-remote-server--read-from-remote-source--read-from-remote-master 选项。

  2. 或者,将源服务器的二进制日志文件复制到副本。您可以使用 mysqlbinlog 从副本中复制,使用 --read-from-remote-server--raw 选项。这些可以通过使用 mysqlbinlog > *file*(不使用 --raw 选项)将二进制日志文件导出到 SQL 文件,然后将这些文件传递给 mysql 客户端进行处理。确保所有二进制日志文件都使用单个 mysql 进程处理,而不是多个连接。例如:

    $> mysqlbinlog copied-binlog.000001 copied-binlog.000002 | mysql -u root -p
    

    有关更多信息,请参见 第 6.6.9.3 节“使用 mysqlbinlog 备份二进制日志文件”。

这种方法的优势在于几乎立即可以获得新服务器;只有在重放快照或转储文件时提交的交易才需要从现有源获取。这意味着副本的可用性并非即时,但只需要相对较短的时间即可使副本赶上这些少量剩余交易。

预先复制二进制日志到目标服务器通常比实时从源读取整个事务执行历史要快。然而,当需要时,将这些文件移动到目标可能并不总是可行,由于大小或其他考虑。本节讨论的用于为新副本配置的另外两种方法使用其他方式将有关事务的信息传输到新副本。

注入空事务。 源的全局gtid_executed变量包含在源上执行的所有事务的集合。在拍摄快照以为新服务器配置时,您可以在拍摄快照的服务器上记录gtid_executed的内容,而不是复制二进制日志。在将新服务器添加到复制链之前,只需为源的gtid_executed中包含的每个事务标识符在新服务器上提交一个空事务,就像这样:

SET GTID_NEXT='aaa-bbb-ccc-ddd:N';

BEGIN;
COMMIT;

SET GTID_NEXT='AUTOMATIC';

一旦所有事务标识符都通过使用空事务重新建立,您必须刷新并清除副本的二进制日志,如下所示,其中N是当前二进制日志文件名的非零后缀:

FLUSH LOGS;
PURGE BINARY LOGS TO 'source-bin.00000*N*';

您应该这样做,以防止该服务器在以后被提升为源时通过虚假事务淹没复制流。(FLUSH LOGS语句强制创建一个新的二进制日志文件;PURGE BINARY LOGS清除空事务,但保留它们的标识符。)

这种方法创建了一个本质上是快照的服务器,但随着其二进制日志历史与复制流的收敛(即,与源或源的收敛),它能够成为一个源。这种结果在效果上类似于使用剩余的配置方法获得的效果,我们将在接下来的几段中讨论。

排除具有 gtid_purged 的事务。 源的全局gtid_purged 变量包含已从源的二进制日志中清除的所有事务的集合。与之前讨论的方法一样(参见注入空事务),您可以记录从快照被取得的服务器上的gtid_executed 的值(而不是将二进制日志复制到新服务器)。与以前的方法不同,无需提交空事务(或发出PURGE BINARY LOGS);相反,您可以根据从备份或快照被取得的服务器上的gtid_executed 的值,在复制品上直接设置gtid_purged

与使用空事务的方法一样,此方法创建了一个在功能上是快照的服务器,但随着其二进制日志历史与源和其他复制品的收敛,它可以成为一个源。

恢复 GTID 模式的复制品。 在遇到错误的基于 GTID 的复制设置中恢复复制品时,注入空事务可能无法解决问题,因为事件没有 GTID。

使用 mysqlbinlog 查找下一个事务,这可能是事件后下一个日志文件中的第一个事务。复制直到该事务的COMMIT,确保包括SET @@SESSION.gtid_next。即使您不使用基于行的复制,也可以在命令行客户端中运行二进制日志行事件。

停止复制品并运行您复制的事务。mysqlbinlog 输出将分隔符设置为/*!*/;,因此将其设置回去:

mysql> DELIMITER ;

自动从正确位置重新启动复制:

mysql> SET GTID_NEXT=automatic;
mysql> RESET SLAVE;
mysql> START SLAVE;
Or from MySQL 8.0.22:
mysql> SET GTID_NEXT=automatic;
mysql> RESET REPLICA;
mysql> START REPLICA;

原文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-assign-anon.html

19.1.3.6 从没有 GTIDs 的源到具有 GTIDs 的复制品的复制

从 MySQL 8.0.23 开始,您可以设置复制通道以为尚未具有 GTID 的复制事务分配 GTID。此功能使得可以从未启用 GTIDs 并且不使用基于 GTID 的复制的源服务器复制到启用了 GTIDs 的复制品。如果可以在复制源服务器上启用 GTIDs,如第 19.1.4 节“在线更改 GTID 模式”中所述,请使用该方法。此功能适用于无法启用 GTIDs 的复制源服务器。请注意,与 MySQL 复制的标准相同,此功能不支持从 MySQL 源服务器复制到先前发布系列之前的 MySQL 源服务器,因此 MySQL 5.7 是 MySQL 8.0 复制品的最早支持源。

您可以使用CHANGE REPLICATION SOURCE TO语句的ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS选项在复制通道上启用 GTID 分配。LOCAL分配一个包括复制品自身 UUID(server_uuid设置)的 GTID。*uuid*分配一个包括指定 UUID 的 GTID,例如复制源服务器的server_uuid设置。使用非本地 UUID 可以区分在复制品上发起的事务和在源上发起的事务,以及在多源复制品上,区分在不同源上发起的事务。如果源发送的任何事务已经有 GTID,则保留该 GTID。

重要提示

在任何通道上设置了ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS的复制品无法在需要故障转移时晋升为替换复制源服务器,并且无法使用从复制品备份的备份来恢复复制源服务器。替换或恢复其他使用任何通道上的ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS的复制品也适用相同的限制。

复制品必须设置gtid_mode=ON,且此后不能更改,除非删除ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS=ON设置。如果复制品服务器在未启用 GTIDs 的情况下启动,并为任何复制通道设置了ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS,则设置不会更改,但会向错误日志写入警告消息,解释如何更改情况。

对于多源复制品,您可以混合使用使用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS和不使用的通道。专用于组复制的通道不能使用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS,但是在作为组复制组成员的服务器实例上的另一个源的异步复制通道可以这样做。对于组复制组成员上的通道,请不要将组复制组名称指定为创建 GTID 的 UUID。

在复制通道上使用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS并不等同于为通道引入基于 GTID 的复制。使用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS设置的复制品的 GTID 集合(gtid_executed)不应传输到另一台服务器或与另一台服务器的gtid_executed集合进行比较。分配给匿名事务的 GTID 以及您为其选择的 UUID 仅对该复制品自身的使用具有意义。唯一的例外是启用了ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS的复制品的任何下游复制品,以及从该复制品的备份创建的任何服务器。

如果您设置了任何下游复制品,这些服务器不会启用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS。只有直接从非 GTID 源服务器接收事务的复制品需要在相关复制通道上设置ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS。在该复制品及其下游复制品之间,您可以比较 GTID 集合,从一个复制品故障转移至另一个复制品,并使用备份创建额外的复制品,就像在任何基于 GTID 的复制拓扑中一样。ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS用于从此组外部的非 GTID 服务器接收事务的情况。

使用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS的复制通道与基于 GTID 的复制有以下行为差异:

  • 当应用复制的事务时,将为其分配 GTID(除非它们已经有 GTID)。通常,当事务提交时,GTID 会在复制源服务器上分配,并与事务一起发送到复制品。在多线程复制品上,这意味着 GTID 的顺序不一定与事务的顺序匹配,即使设置了slave-preserve-commit-order=1

  • CHANGE REPLICATION SOURCE TO语句的SOURCE_LOG_FILESOURCE_LOG_POS选项用于定位复制 I/O(接收器)线程,而不是SOURCE_AUTO_POSITION选项。

  • 使用SET GLOBAL sql_replica_skip_counterSET GLOBAL sql_slave_skip_counter语句跳过使用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS设置的复制通道上的事务,而不是提交空事务的方法。有关说明,请参见 Section 19.1.7.3, “Skipping Transactions”。

  • START REPLICA语句的UNTIL SQL_BEFORE_GTIDSUNTIL_SQL_AFTER_GTIDS选项不能用于通道。

  • 函数WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()在 MySQL 8.0.18 中已被弃用,不能与通道一起使用。它的替代品WAIT_FOR_EXECUTED_GTID_SET()可以在整个服务器上工作,可用于等待启用了ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS的服务器的任何下游复制品。要等待启用了ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS的通道赶上不使用 GTIDs 的源,请使用SOURCE_POS_WAIT()函数(从 MySQL 8.0.26 开始)或MASTER_POS_WAIT()函数。

Performance Schema replication_applier_configuration 表显示复制通道上是否为匿名事务分配了 GTIDs,UUID 是什么,以及它是副本服务器的 UUID(LOCAL)还是用户指定的 UUID(UUID)。这些信息也记录在 applier 元数据存储库中。RESET REPLICA ALL语句会重置ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS设置,但RESET REPLICA语句不会。

原文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-restrictions.html

19.1.3.7 GTID 复制的限制

因为基于 GTID 的复制依赖于事务,所以在使用时不支持 MySQL 中其他可用的一些功能。本节提供有关使用 GTID 进行复制的限制和限制的信息。

涉及非事务性存储引擎的更新。 在使用 GTID 时,对使用非事务性存储引擎(如MyISAM)的表进行更新不能与对使用事务性存储引擎(如InnoDB)的表进行更新在同一语句或事务中进行。

这个限制是因为在同一事务中对使用非事务性存储引擎的表进行更新与对使用事务性存储引擎的表进行更新可能导致将多个 GTID 分配给同一事务。

当源和副本为相同表的不同版本使用不同的存储引擎时,可能会出现这些问题,其中一个存储引擎是事务性的,另一个不是。还要注意,对非事务表进行操作的触发器可能是这些问题的原因。

在上述任何情况下,事务和 GTID 之间的一对一对应关系被打破,导致基于 GTID 的复制无法正常运行。

CREATE TABLE ... SELECT 语句。 在 MySQL 8.0.21 之前,当使用基于 GTID 的复制时,不允许使用 CREATE TABLE ... SELECT 语句。当 binlog_format 设置为 STATEMENT 时,CREATE TABLE ... SELECT 语句在二进制日志中记录为一个具有一个 GTID 的事务,但如果使用 ROW 格式,则该语句将记录为具有两个 GTID 的两个事务。如果源使用 STATEMENT 格式,副本使用 ROW 格式,则副本将无法正确处理事务,因此为了防止这种情况,不允许使用 GTID 的 CREATE TABLE ... SELECT 语句。在支持原子 DDL 的存储引擎上,此限制在 MySQL 8.0.21 中解除。在这种情况下,CREATE TABLE ... SELECT 在二进制日志中记录为一个事务。有关更多信息,请参见 Section 15.1.1, “原子数据定义语句支持”。

临时表。binlog_format设置为STATEMENT时,在服务器上使用 GTIDs 时(即当enforce_gtid_consistency系统变量设置为ON时),不能在事务、存储过程、函数和触发器中使用CREATE TEMPORARY TABLEDROP TEMPORARY TABLE语句。当使用 GTIDs 时,可以在这些上下文之外使用它们,前提是设置了autocommit=1。从 MySQL 8.0.13 开始,当binlog_format设置为ROWMIXED时,在使用 GTIDs 时,可以在事务、存储过程、函数或触发器中使用CREATE TEMPORARY TABLEDROP TEMPORARY TABLE语句。这些语句不会写入二进制日志,因此不会被复制到副本。使用基于行的复制意味着副本保持同步,无需复制临时表。如果从事务中删除这些语句导致事务为空,该事务不会写入二进制日志。

阻止执行不支持的语句。 为防止导致基于 GTID 的复制失败的语句执行,启用 GTIDs 时必须在所有服务器上使用--enforce-gtid-consistency选项启动。这将导致本节前面讨论的任何类型的语句执行失败并显示错误。

请注意,只有在为语句启用二进制日志记录时,--enforce-gtid-consistency才会生效。如果服务器上禁用了二进制日志记录,或者如果语句未写入二进制日志因为它们被过滤器移除,那么对于未记录的语句,GTID 一致性不会被检查或强制执行。

有关启用 GTIDs 时其他必需的启动选项的信息,请参阅 Section 19.1.3.4, “Setting Up Replication Using GTIDs”。

跳过事务。 当使用基于 GTID 的复制时,sql_replica_skip_countersql_slave_skip_counter不可用。如果需要跳过事务,请使用源的gtid_executed变量的值。如果已经在复制通道上启用了 GTID 分配,使用CHANGE REPLICATION SOURCE TO语句的ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS选项,则sql_replica_skip_countersql_slave_skip_counter是可用的。更多信息,请参见第 19.1.7.3 节,“跳过事务”。

忽略服务器。 在使用 GTIDs 时,CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的 IGNORE_SERVER_IDS 选项已被弃用,因为已经应用的事务会自动被忽略。在开始基于 GTID 的复制之前,请检查并清除之前在涉及的服务器上设置的所有被忽略的服务器 ID 列表。可以为单个通道发出的SHOW REPLICA STATUS语句显示被忽略的服务器 ID 列表(如果有)。如果没有列表,则Replicate_Ignore_Server_Ids字段为空。

GTID 模式和 mysql_upgrade。 在 MySQL 8.0.16 之前,当服务器启用全局事务标识符(GTIDs)(gtid_mode=ON)时,请不要通过mysql_upgrade--write-binlog选项)启用二进制日志记录。从 MySQL 8.0.16 开始,服务器执行整个 MySQL 升级过程,但在升级过程中禁用二进制日志记录,因此没有问题。

原文:dev.mysql.com/doc/refman/8.0/en/replication-gtids-functions.html

19.1.3.8 操作 GTID 的存储函数示例

本节提供了使用 MySQL 提供的一些内置函数创建的存储函数示例(请参阅第二十七章,存储对象),这些函数可用于与基于 GTID 的复制一起使用,列在此处:

  • GTID_SUBSET():显示一个 GTID 集合是否是另一个的子集。

  • GTID_SUBTRACT():返回一个 GTID 集合中不在另一个中的 GTID。

  • WAIT_FOR_EXECUTED_GTID_SET(): 等待给定 GTID 集合中的所有事务被执行。

有关刚列出的函数的更多信息,请参阅第 14.18.2 节,“与全局事务标识符(GTID)一起使用的函数”。

请注意,在这些存储函数中,分隔符命令已被用于将 MySQL 语句分隔符更改为竖线,如下所示:

mysql> delimiter |

本节中显示的所有存储函数都将 GTID 集合的字符串表示作为参数,因此在与它们一起使用时,GTID 集合必须始终带引号。

此函数在两个 GTID 集合相同时返回非零(true),即使它们的格式不同:

CREATE FUNCTION GTID_IS_EQUAL(gs1 LONGTEXT, gs2 LONGTEXT)
  RETURNS INT
  RETURN GTID_SUBSET(gs1, gs2) AND GTID_SUBSET(gs2, gs1)
|

此函数在两个 GTID 集合不相交时返回非零(true):

CREATE FUNCTION GTID_IS_DISJOINT(gs1 LONGTEXT, gs2 LONGTEXT)
RETURNS INT
  RETURN GTID_SUBSET(gs1, GTID_SUBTRACT(gs1, gs2))
|

此函数在两个 GTID 集合不相交且sum为它们的并集时返回非零(true):

CREATE FUNCTION GTID_IS_DISJOINT_UNION(gs1 LONGTEXT, gs2 LONGTEXT, sum LONGTEXT)
RETURNS INT
  RETURN GTID_IS_EQUAL(GTID_SUBTRACT(sum, gs1), gs2) AND
         GTID_IS_EQUAL(GTID_SUBTRACT(sum, gs2), gs1)
|

此函数返回 GTID 集合的规范形式,全部大写,无空格和无重复,UUID 按字母顺序排列,间隔按数字顺序排列:

CREATE FUNCTION GTID_NORMALIZE(gs LONGTEXT)
RETURNS LONGTEXT
  RETURN GTID_SUBTRACT(gs, '')
|

此函数返回两个 GTID 集合的并集:

CREATE FUNCTION GTID_UNION(gs1 LONGTEXT, gs2 LONGTEXT)
RETURNS LONGTEXT
  RETURN GTID_NORMALIZE(CONCAT(gs1, ',', gs2))
|

此函数返回两个 GTID 集合的交集。

CREATE FUNCTION GTID_INTERSECTION(gs1 LONGTEXT, gs2 LONGTEXT)
RETURNS LONGTEXT
  RETURN GTID_SUBTRACT(gs1, GTID_SUBTRACT(gs1, gs2))
|

此函数返回两个 GTID 集合之间的对称差异,即存在于gs1中但不存在于gs2中的 GTID,以及存在于gs2中但不存在于gs1中的 GTID。

CREATE FUNCTION GTID_SYMMETRIC_DIFFERENCE(gs1 LONGTEXT, gs2 LONGTEXT)
RETURNS LONGTEXT
  RETURN GTID_SUBTRACT(CONCAT(gs1, ',', gs2), GTID_INTERSECTION(gs1, gs2))
|

此函数从 GTID 集合中删除所有具有指定来源的 GTID,并返回剩余的 GTID(如果有的话)。 UUID 是服务器的标识符,事务通常是在server_uuid中的值。

CREATE FUNCTION GTID_SUBTRACT_UUID(gs LONGTEXT, uuid TEXT)
RETURNS LONGTEXT
  RETURN GTID_SUBTRACT(gs, CONCAT(UUID, ':1-', (1 << 63) - 2))
|

此函数充当前一个函数的反向;它仅返回来自具有指定标识符(UUID)的服务器的 GTID 集合中的 GTID。

CREATE FUNCTION GTID_INTERSECTION_WITH_UUID(gs LONGTEXT, uuid TEXT)
RETURNS LONGTEXT
  RETURN GTID_SUBTRACT(gs, GTID_SUBTRACT_UUID(gs, uuid))
|

示例 19.1 验证副本是否最新

内置函数GTID_SUBSET()GTID_SUBTRACT()可用于检查副本是否至少应用了源应用的每个事务。

要使用GTID_SUBSET()执行此检查,请在副本上执行以下语句:

SELECT GTID_SUBSET(*source_gtid_executed*, *replica_gtid_executed*);

如果返回值为 0(false),则意味着 source_gtid_executed 中的一些 GTID 不在 replica_gtid_executed 中,并且副本尚未应用在源上应用的事务,这意味着副本不是最新的。

要使用 GTID_SUBTRACT() 执行相同的检查,在副本上执行以下语句:

SELECT GTID_SUBTRACT(*source_gtid_executed*, *replica_gtid_executed*);

此语句返回在 source_gtid_executed 中但不在 replica_gtid_executed 中的任何 GTID。如果返回任何 GTID,则表示源已应用了一些副本尚未应用的事务,因此副本不是最新的。

示例 19.2 备份和恢复场景

存储函数 GTID_IS_EQUAL()GTID_IS_DISJOINT()GTID_IS_DISJOINT_UNION() 可用于验证涉及多个数据库和服务器的备份和恢复操作。在此示例场景中,server1 包含数据库 db1server2 包含数据库 db2。目标是将数据库 db2 复制到 server1,并且在 server1 上的结果应该是两个数据库的并集。使用的步骤是使用 mysqldump 备份 server2,然后在 server1 上恢复此备份。

运行 mysqldump 时,如果使用了 --set-gtid-purged 参数设置为 ONAUTO(默认值),输出将包含一个 SET @@GLOBAL.gtid_purged 语句,该语句将从 server2gtid_executed 集合添加到 server1gtid_purged 集合中。gtid_purged 包含在给定服务器上已提交但在服务器上任何二进制日志文件中不存在的所有事务的 GTID。当将数据库 db2 复制到 server1 时,必须将在 server2 上提交的事务的 GTID(这些事务不在 server1 的二进制日志文件中)添加到 server1gtid_purged 中,以使集合完整。

存储函数可用于协助此场景中的以下步骤:

  • 使用 GTID_IS_EQUAL() 验证备份操作是否为 SET @@GLOBAL.gtid_purged 语句计算了正确的 GTID 集合。在 server2 上,从 mysqldump 输出中提取该语句,并将 GTID 集合存储到一个本地变量中,例如 $gtid_purged_set。然后执行以下语句:

    server2> SELECT GTID_IS_EQUAL($gtid_purged_set, @@GLOBAL.gtid_executed);
    

    如果结果为 1,则两个 GTID 集合相等,且集合已正确计算。

  • 使用GTID_IS_DISJOINT()验证mysqldump输出中的 GTID 集与server1上的gtid_executed集不重叠。在两个服务器上存在相同的 GTID 会导致将数据库db2复制到server1时出现错误。要检查,在server1上,从输出中提取并存储gtid_purged到一个本地变量中,然后执行以下语句:

    server1> SELECT GTID_IS_DISJOINT($gtid_purged_set, @@GLOBAL.gtid_executed);
    

    如果结果为 1,则两个 GTID 集之间没有重叠,因此不存在重复的 GTID。

  • 使用GTID_IS_DISJOINT_UNION()验证还原操作是否在server1上导致正确的 GTID 状态。在还原备份之前,在server1上执行以下语句获取现有的gtid_executed集:

    server1> SELECT @@GLOBAL.gtid_executed;
    

    将结果存储在本地变量$original_gtid_executed中,以及如前所述,将gtid_purged中的集合存储在另一个本地变量中。当从server2恢复备份到server1时,执行以下语句验证 GTID 状态:

    server1> SELECT 
     ->   GTID_IS_DISJOINT_UNION($original_gtid_executed,
     ->                          $gtid_purged_set,
     ->                          @@GLOBAL.gtid_executed);
    

    如果结果为1,则存储的函数已验证来自server1的原始gtid_executed集($original_gtid_executed)和从server2添加的gtid_purged集($gtid_purged_set)没有重叠,并且server1上更新的gtid_executed集现在包括来自server1的先前gtid_executed集以及来自server2gtid_purged集,这是期望的结果。确保在server1上发生任何进一步的事务之前进行此检查,否则gtid_executed中的新事务将导致其失败。

示例 19.3 选择最新的副本进行手动故障转移

存储函数GTID_UNION()可用于从一组副本中识别最新的副本,以便在源服务器意外停止后执行手动故障转移操作。如果一些副本正在经历复制延迟,此存储函数可用于计算最新的副本,而无需等待所有副本应用其现有的中继日志,从而最小化故障转移时间。该函数可以返回每个副本上的gtid_executed与副本接收到的事务集的并集,该事务集记录在性能模式replication_connection_status表中。您可以比较这些结果,找出哪个副本的事务记录是最新的,即使并非所有事务都已提交。

在每个副本上,通过执行以下语句计算完整的事务记录:

SELECT GTID_UNION(RECEIVED_TRANSACTION_SET, @@GLOBAL.gtid_executed)
    FROM performance_schema.replication_connection_status
    WHERE channel_name = 'name';

然后可以比较每个副本的结果,看哪个副本具有最新的事务记录,并将此副本用作新的源。

示例 19.4 检查副本上的多余交易

存储函数GTID_SUBTRACT_UUID()可用于检查副本是否接收了未来自其指定来源或来源的交易。如果有,则可能存在复制设置问题,或代理、路由器或负载均衡器存在问题。此函数通过从指定起始服务器的 GTID 集合中移除所有 GTID,并返回剩余的 GTID(如果有)来工作。

对于具有单个来源的副本,请发出以下语句,提供起始来源的标识符,通常与server_uuid相同:

SELECT GTID_SUBTRACT_UUID(@@GLOBAL.gtid_executed, server_uuid_of_source);

如果结果不为空,则返回的交易是未来自指定来源的额外交易。

对于多源拓扑中的副本,请在函数调用中包含每个来源的服务器 UUID,如下所示:

SELECT 
  GTID_SUBTRACT_UUID(GTID_SUBTRACT_UUID(@@GLOBAL.gtid_executed,
                                        server_uuid_of_source_1),
                                        server_uuid_of_source_2);

如果结果不为空,则返回的交易是未来自任何指定来源的额外交易。

示例 19.5 验证复制拓扑中的服务器是否为只读

存储函数GTID_INTERSECTION_WITH_UUID()可用于验证服务器是否未发起任何 GTID 并处于只读状态。该函数仅返回来自具有指定标识符的服务器的 GTID 集合中的那些 GTID。如果在此服务器的gtid_executed中列出的任何交易使用服务器自己的标识符,则服务器本身发起了这些交易。您可以在服务器上发出以下语句进行检查:

SELECT GTID_INTERSECTION_WITH_UUID(@@GLOBAL.gtid_executed, my_server_uuid);

示例 19.6 在多源复制中验证额外的副本

存储函数GTID_INTERSECTION_WITH_UUID()可用于查找附加到多源复制设置的副本是否已应用来自一个特定源的所有事务。在这种情况下,source1source2都是源和副本,并相互复制。source2还有自己的副本。如果source2配置为log_replica_updates=ON,则副本还会接收并应用来自source1的事务,但如果source2使用log_replica_updates=OFF,则不会这样做。无论哪种情况,我们目前只想知道副本是否与source2保持同步。在这种情况下,GTID_INTERSECTION_WITH_UUID()可用于识别source2发起的事务,丢弃source2source1复制的事务。然后可以使用内置函数GTID_SUBSET()将结果与副本上的gtid_executed集进行比较。如果副本与source2保持同步,则副本上的gtid_executed集包含交集集中的所有事务(源自source2的事务)。

要执行此检查,请将source2gtid_executed值和服务器 UUID 以及副本中的gtid_executed值存储到用户变量中,如下所示:

source2> SELECT @@GLOBAL.gtid_executed INTO @source2_gtid_executed;

source2> SELECT @@GLOBAL.server_uuid INTO @source2_server_uuid;

replica> SELECT @@GLOBAL.gtid_executed INTO @replica_gtid_executed;

然后使用GTID_INTERSECTION_WITH_UUID()GTID_SUBSET(),并将这些变量作为输入,如下所示:

SELECT 
  GTID_SUBSET(
    GTID_INTERSECTION_WITH_UUID(@source2_gtid_executed,
                                @source2_server_uuid),
                                @replica_gtid_executed);

来自source2的服务器标识符(@source2_server_uuid)与GTID_INTERSECTION_WITH_UUID()一起使用,仅识别并返回那些在source2上发起的 GTID,省略那些在source1上发起的。然后,使用GTID_SUBSET()将生成的 GTID 集与副本上的所有已执行 GTID 集进行比较。如果此语句返回非零(true),则从source2识别的所有 GTID(第一个输入集)也在副本的gtid_executed中找到,这意味着副本已接收并执行了所有源自source2的事务。

19.1.4 在在线服务器上更改 GTID 模式

原文:dev.mysql.com/doc/refman/8.0/en/replication-mode-change-online.html

19.1.4.1 复制模式概念

19.1.4.2 在线启用 GTID 事务

19.1.4.3 在线禁用 GTID 事务

19.1.4.4 验证匿名事务的复制

本节描述如何在不必使服务器脱机的情况下更改复制模式从 GTID 模式到其他模式。

原文:dev.mysql.com/doc/refman/8.0/en/replication-mode-change-online-concepts.html

19.1.4.1 复制模式概念

在设置在线服务器的复制模式之前,了解一些复制的关键概念非常重要。本节解释了这些概念,在尝试修改在线服务器的复制模式之前,这是必读的内容。

MySQL 中可用的复制模式依赖于不同的技术来识别已记录的事务。复制使用的事务类型在此处列出:

  • GTID 事务由全局事务标识符(GTID)标识,其形式为UUID:NUMBER。二进制日志中的每个 GTID 事务都以Gtid_log_event开头。GTID 事务可以通过其 GTID 或记录在其中的文件的名称及其在该文件中的位置来寻址。

  • 匿名事务没有 GTID;MySQL 8.0 确保日志中的每个匿名事务都以Anonymous_gtid_log_event开头。(在 MySQL 的先前版本中,匿名事务不会以任何特定事件开头。)匿名事务只能通过文件名和位置来寻址。

使用 GTID 时,您可以利用 GTID 自动定位和自动故障转移,并使用WAIT_FOR_EXECUTED_GTID_SET()session_track_gtids和性能模式表来监视复制事务(请参阅第 29.12.11 节,“性能模式复制表”)。

来自运行先前版本的 MySQL 的源的中继日志中的事务可能不会以任何特定事件开头,但在被重放并记录在副本的二进制日志中之后,它将以Anonymous_gtid_log_event开头。

要在线更改复制模式,需要使用具有足够权限设置全局系统变量的帐户来设置gtid_modeenforce_gtid_consistency变量;请参阅第 7.1.9.1 节,“系统变量权限”。gtid_mode的允许值按顺序列在此处,并附有其含义:

  • OFF:只有匿名事务可以被复制。

  • OFF_PERMISSIVE:新事务是匿名的;复制的事务可以是 GTID 或匿名的。

  • ON_PERMISSIVE:新事务使用 GTID;复制的事务可以是 GTID 或匿名的。

  • ON:所有事务必须具有 GTID;匿名事务无法被复制。

可以在同一复制拓扑中同时使用匿名事务和 GTID 事务的服务器。例如,一个源,其中gtid_mode=ON可以复制到一个副本,其中gtid_mode=ON_PERMISSIVE

gtid_mode只能一次更改一步,根据前面列表中显示的值的顺序。例如,如果gtid_mode设置为OFF_PERMISSIVE,则可以将其更改为OFFON_PERMISSIVE,但不能更改为ON。这是为了确保服务器正确处理从匿名事务到 GTID 事务在线更改的过程;GTID 状态(即gtid_executed的值)是持久的。这确保了服务器应用的 GTID 设置始终保留并正确,而不受gtid_mode值的任何更改影响。

显示 GTID 集的系统变量,如gtid_executedgtid_purged,性能模式replication_connection_status表的RECEIVED_TRANSACTION_SET列,以及SHOW REPLICA STATUS输出中与 GTID 相关的结果,当没有 GTID 时都返回空字符串。关于单个 GTID 的信息来源,例如性能模式replication_applier_status_by_worker表中显示的CURRENT_TRANSACTION列中显示ANONYMOUS,当未使用 GTID 事务时。

使用gtid_mode=ON从源复制提供了使用 GTID 自动定位的能力,通过CHANGE REPLICATION SOURCE TO语句的SOURCE_AUTO_POSITION选项进行配置。正在使用的复制拓扑结构会影响是否可以启用自动定位,因为此功能依赖于 GTIDs,并且与匿名事务不兼容。强烈建议在启用自动定位之前确保拓扑结构中没有匿名事务;参见第 19.1.4.2 节,“在线启用 GTID 事务”。

源和副本上 gtid_mode 和自动定位的有效组合如下表所示。每个条目的含义如下:

  • Y: 源和副本上的 gtid_mode 的值兼容。

  • N: 源和副本上的 gtid_mode 的值不兼容。

  • *: 可以使用此值组合进行自动定位。

表 19.1 源和副本 gtid_mode 的有效组合

gtid_mode OFF OFF_PERMISSIVE ON_PERMISSIVE ON
副本 OFF Y Y N N
副本 OFF_PERMISSIVE Y Y Y Y*
副本 ON_PERMISSIVE Y Y Y Y*
副本 ON N N Y Y*

当前的 gtid_mode 值也会影响 gtid_next。下表显示了服务器对不同值的 gtid_modegtid_next 组合的行为。每个条目的含义如下:

  • 匿名: 生成匿名事务。

  • 错误: 生成错误,并且不执行 SET GTID_NEXT

  • UUID:NUMBER: 生成具有指定 UUID:NUMBER 的 GTID。

  • 新 GTID: 生成带有自动生成编号的 GTID。

表 19.2 gtid_mode 和 gtid_next 的有效组合

gtid_next 自动二进制日志开启 gtid_next 自动二进制日志关闭 gtid_next 匿名 gtid_next UUID:NUMBER
gtid_mode OFF 匿名 匿名 匿名 错误
gtid_mode OFF_PERMISSIVE 匿名 匿名 匿名 UUID:NUMBER
gtid_mode ON_PERMISSIVE 新 GTID 匿名 匿名 UUID:NUMBER
gtid_mode ON 新 GTID 匿名 错误 UUID:NUMBER

当未使用二进制日志记录且 gtid_nextAUTOMATIC 时,不会生成任何 GTID,这与 MySQL 之前版本的行为一致。

原文:dev.mysql.com/doc/refman/8.0/en/replication-mode-change-online-enable-gtids.html

19.1.4.2 启用 GTID 事务在线

本节描述了如何在已在线并使用匿名事务的服务器上启用 GTID 事务,以及可选的自动定位。此过程不需要将服务器脱机,并适用于生产环境。但是,如果在启用 GTID 事务时有可能将服务器脱机,则该过程更容易。

从 MySQL 8.0.23 开始,您可以设置复制通道,为尚未具有 GTID 的复制事务分配 GTID。此功能使得可以从不使用基于 GTID 的复制的源服务器复制到使用该功能的副本服务器。如果可能在复制源服务器上启用 GTID,如本过程中所述,请使用此方法。分配 GTID 适用于无法启用 GTID 的复制源服务器。有关此选项的更多信息,请参阅第 19.1.3.6 节,“从不具有 GTID 的源复制到具有 GTID 的副本”。

在开始之前,请确保服务器满足以下先决条件:

  • 您的拓扑中的所有服务器必须使用 MySQL 5.7.6 或更高版本。除非所有拓扑中的服务器都使用此版本,否则无法在任何单个服务器上在线启用 GTID 事务。

  • 所有服务器的gtid_mode设置为默认值OFF

以下过程可以随时暂停,并在原地恢复,或通过跳转到第 19.1.4.3 节,“在线禁用 GTID 事务”的相应步骤来撤销。这使得该过程具有容错性,因为在过程中可能出现的任何不相关问题都可以像往常一样处理,然后继续在离开的地方继续进行。

注意

在继续下一步之前,您必须完成每个步骤。

要启用 GTID 事务:

  1. 在每台服务器上执行:

    SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
    

    让服务器在正常工作负载下运行一段时间,并监视日志。如果此步骤在日志中引发任何警告,请调整应用程序,使其仅使用 GTID 兼容功能,并且不生成任何警告。

    重要

    这是第一个重要的步骤。在继续下一步之前,您必须确保错误日志中没有生成任何警告。

  2. 在每台服务器上执行:

    SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
    
  3. 在每台服务器上执行:

    SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
    

    不重要哪个服务器首先执行此语句,但重要的是所有服务器在任何服务器开始下一步之前完成此步骤。

  4. 在每台服务器上执行:

    SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
    

    这个语句首先由哪台服务器执行并不重要。

  5. 在每台服务器上,等待直到状态变量 ONGOING_ANONYMOUS_TRANSACTION_COUNT 为零。可以使用以下方式进行检查:

    SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
    

    注意

    在副本上,理论上可能会显示零,然后再次显示非零。这不是问题,只要它显示零一次即可。

  6. 等待生成到第 5 步的所有事务复制到所有服务器。您可以在不停止更新的情况下执行此操作:唯一重要的是所有匿名事务都得到复制。

    参见 Section 19.1.4.4, “验证匿名事务的复制” 以了解检查所有匿名事务是否已复制到所有服务器的一种方法。

  7. 如果您将二进制日志用于除复制之外的任何其他用途,例如时间点备份和恢复,请等到您不再需要具有不带 GTIDs 事务的旧二进制日志。

    例如,在第 6 步完成后,您可以在正在进行备份的服务器上执行 FLUSH LOGS。然后要么明确地进行备份,要么等待您设置的任何定期备份例程的下一次迭代。

    理想情况下,等待服务器清除在完成第 6 步时存在的所有二进制日志。还要等待在第 6 步之前进行的任何备份过期。

    重要

    这是第二个重要的要点。理解二进制日志中包含的匿名事务,如果没有 GTIDs,在下一步之后将无法使用。在此步骤之后,您必须确保在拓扑结构中不存在不带 GTIDs 的事务。

  8. 在每台服务器上执行:

    SET @@GLOBAL.GTID_MODE = ON;
    
  9. 在每台服务器上,将 gtid_mode=ONenforce_gtid_consistency=ON 添加到 my.cnf

    现在,您可以确保所有事务都具有 GTID(除了在第 5 步或更早生成的事务已经被处理)。为了开始使用 GTID 协议,以便稍后执行自动故障转移,在每个副本上执行以下操作。可选地,如果使用多源复制,请为每个通道执行此操作,并包括 FOR CHANNEL *channel* 子句:

    STOP SLAVE [FOR CHANNEL 'channel'];
    CHANGE MASTER TO MASTER_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
    START SLAVE [FOR CHANNEL 'channel'];
    
    Or from MySQL 8.0.22 / 8.0.23:
    STOP REPLICA [FOR CHANNEL 'channel'];
    CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
    START REPLICA [FOR CHANNEL 'channel'];
    

原文:dev.mysql.com/doc/refman/8.0/en/replication-mode-change-online-disable-gtids.html

19.1.4.3 在线禁用 GTID 事务

本节描述了如何在已经在线的服务器上禁用 GTID 事务。此过程无需将服务器脱机,并适用于在生产环境中使用。但是,如果您有可能在禁用 GTID 模式时将服务器脱机,那么该过程会更加简单。

该过程类似于在服务器在线时启用 GTID 事务,但是步骤相反。唯一不同的是等待已记录事务复制的时间点。

在开始之前,请确保服务器满足以下先决条件:

  • 您的拓扑中的所有服务器必须使用 MySQL 5.7.6 或更高版本。除非拓扑中的所有服务器都使用此版本,否则无法在线禁用 GTID 事务。

  • 所有服务器的gtid_mode设置为ON

  • 任何服务器上都未设置--replicate-same-server-id选项。如果此选项与--log-slave-updates选项(默认情况下)和启用了二进制日志记录(也是默认情况)一起设置,则无法禁用 GTID 事务。在没有 GTID 的情况下,这些选项的组合会在循环复制中导致无限循环。

  1. 在每个副本上执行以下操作,如果您正在使用多源复制,请为每个通道执行,并包括FOR CHANNEL通道子句:

    STOP SLAVE [FOR CHANNEL 'channel'];
    CHANGE MASTER TO MASTER_AUTO_POSITION = 0, MASTER_LOG_FILE = file, \
    MASTER_LOG_POS = position [FOR CHANNEL 'channel'];
    START SLAVE [FOR CHANNEL 'channel'];
    
    Or from MySQL 8.0.22 / 8.0.23:
    STOP REPLICA [FOR CHANNEL 'channel'];
    CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 0, SOURCE_LOG_FILE = file, \
    SOURCE_LOG_POS = position [FOR CHANNEL 'channel'];
    START REPLICA [FOR CHANNEL 'channel'];
    
  2. 在每台服务器上执行:

    SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
    
  3. 在每台服务器上执行:

    SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
    
  4. 在每台服务器上,等待变量@@GLOBAL.GTID_OWNED 等于空字符串。可以使用以下方式进行检查:

    SELECT @@GLOBAL.GTID_OWNED;
    

    理论上,在副本上,这可能为空,然后再次变为非空。这不是问题,只要它曾经为空就足够了。

  5. 等待当前存在于任何二进制日志中的所有事务在所有副本中复制。参见 Section 19.1.4.4, “验证匿名事务的复制”,了解检查所有匿名事务是否已复制到所有服务器的一种方法。

  6. 如果您将二进制日志用于除复制之外的任何其他用途,例如进行时间点备份或还原:请等待您不再需要具有 GTID 事务的旧二进制日志。

    例如,在完成第 5 步之后,您可以在正在进行备份的服务器上执行FLUSH LOGS。然后,要么明确进行备份,要么等待您设置的任何定期备份例程的下一次迭代。

    理想情况下,等待服务器清除在步骤 5 完成时存在的所有二进制日志。还要等待在步骤 5 之前备份的任何备份过期。

    重要提示

    这是整个过程中的一个重要点。重要的是要理解,包含 GTID 事务的日志在下一步之后不能再使用。在继续之前,您必须确保拓扑结构中不存在任何 GTID 事务。

  7. 在每台服务器上执行:

    SET @@GLOBAL.GTID_MODE = OFF;
    
  8. 在每台服务器上,在 my.cnf 中设置 gtid_mode=OFF

    如果您想设置 enforce_gtid_consistency=OFF,现在可以这样做。设置后,您应该将 enforce_gtid_consistency=OFF 添加到您的配置文件中。

如果您想降级到 MySQL 的早期版本,现在可以使用正常的降级过程进行操作。

原文:dev.mysql.com/doc/refman/8.0/en/replication-mode-change-online-verify-transactions.html

19.1.4.4 验证匿名事务的复制

本节解释了如何监视复制拓扑并验证所有匿名事务是否已被复制。在在线更改复制模式时,这很有帮助,因为您可以验证更改为 GTID 事务是安全的。

有几种等待事务复制的可能方法:

最简单的方法是,无论您的拓扑如何,但依赖于时间的方法如下:如果您确信副本永远不会落后于 N 秒,只需等待多于 N 秒。或者等待一天,或者您认为对于您的部署是安全的任何时间段。

在某种意义上更安全的方法,因为它不依赖于时间:如果您只有一个带有一个或多个副本的源,则执行以下操作:

  1. 在源端执行:

    SHOW MASTER STATUS;
    

    记下“文件”和“位置”列中的值。

  2. 在每个副本上,使用源端的文件和位置信息执行:

    SELECT MASTER_POS_WAIT(file, position);
    
    Or from MySQL 8.0.26:
    SELECT SOURCE_POS_WAIT(file, position);
    

如果您有一个源和多个级别的副本,或者换句话说,您有副本的副本,请从源开始,然后在每个级别上重复步骤 2,然后所有直接副本,然后所有副本的副本,依此类推。

如果您使用循环复制拓扑,其中多个服务器可能有写客户端,请为每个源-副本连接执行步骤 2,直到完成整个循环。重复整个过程,以便完成整个循环两次

例如,假设您有三台服务器 A、B 和 C,在一个循环中进行复制,即 A -> B -> C -> A。然后,操作步骤如下:

  • 在 A 上执行步骤 1,在 B 上执行步骤 2。

  • 在 B 上执行步骤 1,在 C 上执行步骤 2。

  • 在 C 上执行步骤 1,在 A 上执行步骤 2。

  • 在 A 上执行步骤 1,在 B 上执行步骤 2。

  • 在 B 上执行步骤 1,在 C 上执行步骤 2。

  • 在 C 上执行步骤 1,在 A 上执行步骤 2。

19.1.5 MySQL 多源复制

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source.html

19.1.5.1 配置多源复制

19.1.5.2 为基于 GTID 的复制配置多源复制副本

19.1.5.3 向多源复制副本添加基于 GTID 的源

19.1.5.4 向多源复制副本添加基于二进制日志的复制源

19.1.5.5 启动多源复制副本

19.1.5.6 停止多源复制副本

19.1.5.7 重置多源复制副本

19.1.5.8 监控多源复制

MySQL 多源复制使副本能够并行接收来自多个直接源的事务。在多源复制拓扑中,副本为应该接收事务的每个源创建一个复制通道。有关复制通道功能的更多信息,请参见第 19.2.2 节,“复制通道”。

您可能选择实现多源复制以实现以下目标:

  • 将多个服务器备份到单个服务器。

  • 合并表分片。

  • 将数据从多个服务器整合到单个服务器。

多源复制在应用事务时不实现任何冲突检测或解决方案,如果需要,这些任务由应用程序自行处理。

注意

多源复制副本上的每个通道必须从不同的源复制。您不能从单个副本设置多个复制通道到单个源。这是因为在复制拓扑中,副本的服务器 ID 必须是唯一的。源仅通过副本的服务器 ID 区分副本,而不是通过复制通道的名称,因此它无法识别来自同一副本的不同复制通道。

多源复制副本也可以设置为多线程复制副本,方法是将系统变量replica_parallel_workers(从 MySQL 8.0.26 开始)或slave_parallel_workers设置为大于 0 的值。当在多源复制副本上执行此操作时,副本上的每个通道都有指定数量的应用程序线程,以及一个协调器线程来管理它们。您无法为单个通道配置应用程序线程的数量。

从 MySQL 8.0 开始,可以在特定复制通道上配置多源副本的复制过滤器。当相同数据库或表存在于多个源上,并且您只需要副本从一个源复制它时,可以使用特定通道的复制过滤器。对于基于 GTID 的复制,如果同一事务可能来自多个源(例如在钻石拓扑中),您必须确保所有通道上的过滤设置相同。有关更多信息,请参见 Section 19.2.5.4, “Replication Channel Based Filters”。

本节提供了关于如何配置多源复制的源和副本、如何启动、停止和重置多源副本以及如何监控多源复制的教程。

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-configuration.html

19.1.5.1 配置多源复制

多源复制拓扑至少需要配置两个源和一个副本。在这些教程中,我们假设您有两个源source1source2,以及一个副本replicahost。副本从每个源复制一个数据库,从source1复制db1,从source2复制db2

多源复制拓扑中的源可以配置为使用基于 GTID 的复制,或者基于二进制日志位置的复制。查看第 19.1.3.4 节,“使用 GTIDs 设置复制”了解如何配置使用基于 GTID 的复制的源。查看第 19.1.2.1 节,“设置复制源配置”了解如何配置使用基于文件位置的复制的源。

多源复制拓扑中的副本需要TABLE存储库用于副本的连接元数据存储库和应用程序元数据存储库,这在 MySQL 8.0 中是默认的。多源复制与已弃用的替代文件存储库不兼容。

在所有副本上创建一个适当的用户帐户,副本可以使用该帐户进行连接。您可以在所有源上使用相同的帐户,或者在每个源上使用不同的帐户。如果您仅为复制目的创建一个帐户,则该帐户只需要REPLICATION SLAVE权限。例如,要设置一个名为ted的新用户,该用户可以从副本replicahost连接,请使用mysql客户端在每个源上发出以下语句:

mysql> CREATE USER 'ted'@'replicahost' IDENTIFIED BY '*password*';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'ted'@'replicahost';

有关更多详细信息,以及关于 MySQL 8.0 新用户默认身份验证插件的重要信息,请参阅第 19.1.2.3 节,“为复制创建用户”。

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-provision-replica.html

19.1.5.2 为基于 GTID 的复制提供多源副本

如果多源复制拓扑中的源具有现有数据,可以在开始复制之前使用相关数据为副本提供数据以节省时间。在多源复制拓扑中,无法使用克隆或复制数据目录来为副本提供来自所有源的数据,您可能还想要仅从每个源复制特定数据库。因此,为此类副本提供数据的最佳策略是使用mysqldump在每个源上创建适当的转储文件,然后使用mysql客户端在副本上导入转储文件。

如果您正在使用基于 GTID 的复制,请注意SET @@GLOBAL.gtid_purged语句,该语句由mysqldump放置在转储输出中。此语句将源上执行的事务的 GTID 传输到副本,副本需要这些信息。然而,对于比从一个源为一个新的空副本提供更复杂的情况,您需要检查该语句在副本使用的 MySQL 版本中的影响,并相应处理该语句。以下指导总结了适当的操作,但更多详情请参阅mysqldump文档。

mysqldump编写的SET @@GLOBAL.gtid_purged语句在 MySQL 8.0 的版本中与 MySQL 5.6 和 5.7 中的行为不同。在 MySQL 5.6 和 5.7 中,该语句替换了副本上的gtid_purged的值,并且在这些版本中,只有在副本的具有 GTID 的事务记录(gtid_executed集)为空时才能更改该值。在多源复制拓扑中,因此在重放转储文件之前必须从转储输出中删除SET @@GLOBAL.gtid_purged语句,因为不能应用包含此语句的第二个或后续转储文件。还要注意,在 MySQL 5.6 和 5.7 中,这个限制意味着必须在具有空的gtid_executed集的副本上以单个操作应用所有源的转储文件。您可以通过在副本上发出RESET MASTER来清除副本的 GTID 执行历史,但如果在副本上有其他需要的带有 GTID 的事务,请选择从 Section 19.1.3.5, “Using GTIDs for Failover and Scaleout”中描述的方法中选择一种替代方法进行配置。

从 MySQL 8.0 开始,SET @@GLOBAL.gtid_purged语句将从转储文件中的 GTID 集添加到副本上现有的gtid_purged集中。因此,在副本上重放转储文件时,该语句可能会留在转储输出中,并且可以在不同时间重放转储文件。然而,重要的是要注意,mysqldumpSET @@GLOBAL.gtid_purged语句包含的值包括源上gtid_executed集中所有事务的 GTID,即使这些事务更改了数据库的被抑制部分,或者服务器上未包含在部分转储中的其他数据库。如果在副本上重放包含任何相同 GTID 的第二个或后续转储文件(例如,来自相同源的另一个部分转储,或者来自具有重叠事务的另一个源的转储),第二个转储文件中的任何SET @@GLOBAL.gtid_purged语句将失败,因此必须从转储输出中删除。

对于来自 MySQL 8.0.17 的源,作为删除SET @@GLOBAL.gtid_purged语句的替代方案,您可以将mysqldump--set-gtid-purged选项设置为COMMENTED,以包含该语句但注释掉,这样在加载转储文件时不会执行该语句。如果您正在使用来自同一源的两个部分转储文件为副本提供数据,并且第二个转储文件中的 GTID 集合与第一个相同(因此在转储之间源上没有执行新事务),则可以在输出第二个转储文件时将mysqldump--set-gtid-purged选项设置为OFF,以省略该语句。

在以下配置示例中,我们假设SET @@GLOBAL.gtid_purged语句不能保留在转储输出中,并且必须从���件中删除并手动处理。我们还假设在开始配置之前,在副本上没有带有 GTID 的想要的事务。

  1. 要为名为source1上的名为db1的数据库和名为source2上的名为db2的数据库创建转储文件,请按以下方式为source1运行mysqldump

    mysqldump -u<*user*> -p<*password*> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db1 > dumpM1.sql
    

    然后按以下方式为source2运行mysqldump

    mysqldump -u<*user*> -p<*password*> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db2 > dumpM2.sql
    
  2. 记录gtid_purged值,该值是mysqldump添加到每个转储文件中的。例如,对于在 MySQL 5.6 或 5.7 上创建的转储文件,可以像这样提取该值:

    cat dumpM1.sql | grep GTID_PURGED | cut -f2 -d'=' | cut -f2 -d$'\''
    cat dumpM2.sql | grep GTID_PURGED | cut -f2 -d'=' | cut -f2 -d$'\''
    

    从 MySQL 8.0 开始,格式已更改,您可以像这样提取该值:

    cat dumpM1.sql | grep GTID_PURGED | perl -p0 -e 's#/\*.*?\*/##sg' | cut -f2 -d'=' | cut -f2 -d$'\''
    cat dumpM2.sql | grep GTID_PURGED | perl -p0 -e 's#/\*.*?\*/##sg' | cut -f2 -d'=' | cut -f2 -d$'\''
    

    每种情况下的结果应该是一个 GTID 集合,例如:

    source1:   2174B383-5441-11E8-B90A-C80AA9429562:1-1029
    source2:   224DA167-0C0C-11E8-8442-00059A3C7B00:1-2695
    
  3. 从每个转储文件中删除包含SET @@GLOBAL.gtid_purged语句的行。例如:

    sed '/GTID_PURGED/d' dumpM1.sql > dumpM1_nopurge.sql
    sed '/GTID_PURGED/d' dumpM2.sql > dumpM2_nopurge.sql
    
  4. 使用mysql客户端将每个编辑过的转储文件导入到副本中。例如:

    mysql -u<*user*> -p<*password*> < dumpM1_nopurge.sql
    mysql -u<*user*> -p<*password*> < dumpM2_nopurge.sql
    
  5. 在副本上,发出RESET MASTER以清除 GTID 执行历史记录(假设,如上所述,所有转储文件都已导入,并且在副本上没有带有 GTID 的想要的事务)。然后发出SET @@GLOBAL.gtid_purged语句,将gtid_purged值设置为所有转储文件中所有 GTID 集合的并集,就像在第 2 步中记录的那样。例如:

    mysql> RESET MASTER;
    mysql> SET @@GLOBAL.gtid_purged = "2174B383-5441-11E8-B90A-C80AA9429562:1-1029, 224DA167-0C0C-11E8-8442-00059A3C7B00:1-2695";
    

    如果在转储文件中的 GTID 集合之间存在或可能存在重叠的事务,则可以使用 Section 19.1.3.8, “操作 GTID 的存储函数示例”中描述的存储函数事先检查这一点,并计算所有 GTID 集合的并集。

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-adding-gtid-master.html

19.1.5.3 向多源副本添加基于 GTID 的源

这些步骤假定您已经在源上使用gtid_mode=ON启用了事务的 GTIDs,创建了一个复制用户,确保副本正在使用基于TABLE的复制应用程序元数据存储库,并根据需要为副本提供了来自源的数据。

使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(MySQL 8.0.23 之前)在副本上为每个源配置一个复制通道(参见 Section 19.2.2, “Replication Channels”)。FOR CHANNEL子句用于指定通道。对于基于 GTID 的复制,使用 GTID 自动定位来与源进行同步(参见 Section 19.1.3.3, “GTID Auto-Positioning”)。设置SOURCE_AUTO_POSITION | MASTER_AUTO_POSITION选项以指定使用自动定位。

例如,要将source1source2添加为副本的源,请使用mysql客户端在副本上发出两次语句,如下所示:

mysql> CHANGE MASTER TO MASTER_HOST="source1", MASTER_USER="ted", \
MASTER_PASSWORD="*password*", MASTER_AUTO_POSITION=1 FOR CHANNEL "source_1";
mysql> CHANGE MASTER TO MASTER_HOST="source2", MASTER_USER="ted", \
MASTER_PASSWORD="*password*", MASTER_AUTO_POSITION=1 FOR CHANNEL "source_2";

Or from MySQL 8.0.23:
mysql> CHANGE REPLICATION SOURCE TO SOURCE_HOST="source1", SOURCE_USER="ted", \
SOURCE_PASSWORD="*password*", SOURCE_AUTO_POSITION=1 FOR CHANNEL "source_1";
mysql> CHANGE REPLICATION SOURCE TO SOURCE_HOST="source2", SOURCE_USER="ted", \
SOURCE_PASSWORD="*password*", SOURCE_AUTO_POSITION=1 FOR CHANNEL "source_2";

要使副本仅从source1复制数据库db1,并且仅从source2复制数据库db2,请使用mysql客户端为每个通道发出CHANGE REPLICATION FILTER语句,如下所示:

mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db1.%') FOR CHANNEL "source_1";
mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db2.%') FOR CHANNEL "source_2";

有关CHANGE REPLICATION FILTER语句的完整语法和其他可用选项,请参见 Section 15.4.2.2, “CHANGE REPLICATION FILTER Statement”。

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-adding-binlog-master.html

19.1.5.4 将基于二进制日志的复制源添加到多源复制副本

这些步骤假定源上已启用二进制日志记录(这是默认设置),副本正在使用基于TABLE的复制应用程序元数据存储库(这是 MySQL 8.0 中的默认设置),并且您已启用了一个复制用户并记录了当前的二进制日志文件名和位置。

使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)为副本上的每个源配置一个复制通道(请参见 Section 19.2.2, “Replication Channels”)。FOR CHANNEL子句用于指定通道。例如,要将source1source2添加为副本的源,请使用mysql客户端在副本上两次发出该语句,如下所示:

mysql> CHANGE MASTER TO MASTER_HOST="source1", MASTER_USER="ted", MASTER_PASSWORD="*password*", \
MASTER_LOG_FILE='source1-bin.000006', MASTER_LOG_POS=628 FOR CHANNEL "source_1";
mysql> CHANGE MASTER TO MASTER_HOST="source2", MASTER_USER="ted", MASTER_PASSWORD="*password*", \
MASTER_LOG_FILE='source2-bin.000018', MASTER_LOG_POS=104 FOR CHANNEL "source_2";

Or from MySQL 8.0.23:
mysql> CHANGE REPLICATION SOURCE TO SOURCE_HOST="source1", SOURCE_USER="ted", SOURCE_PASSWORD="*password*", \
SOURCE_LOG_FILE='source1-bin.000006', SOURCE_LOG_POS=628 FOR CHANNEL "source_1";
mysql> CHANGE REPLICATION SOURCE TO SOURCE_HOST="source2", SOURCE_USER="ted", SOURCE_PASSWORD="*password*", \
SOURCE_LOG_FILE='source2-bin.000018', SOURCE_LOG_POS=104 FOR CHANNEL "source_2";

要使副本仅从source1复制数据库db1,并且仅从source2复制数据库db2,请使用mysql客户端为每个通道发出CHANGE REPLICATION FILTER语句,如下所示:

mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db1.%') FOR CHANNEL "source_1";
mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db2.%') FOR CHANNEL "source_2";

对于CHANGE REPLICATION FILTER语句的完整语法和其他可用选项,请参见 Section 15.4.2.2, “CHANGE REPLICATION FILTER Statement”。

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-start-replica.html

19.1.5.5 启动多源复制副本

一旦为所有复制源添加了通道,请发出START REPLICA(或在 MySQL 8.0.22 之前,START SLAVE)语句以开始复制。当您在副本上启用了多个通道时,您可以选择启动所有通道,或选择特定通道启动。例如,要分别启动两个通道,请使用mysql客户端发出以下语句:

mysql> START SLAVE FOR CHANNEL "source_1";
mysql> START SLAVE FOR CHANNEL "source_2";
Or from MySQL 8.0.22:
mysql> START REPLICA FOR CHANNEL "source_1";
mysql> START REPLICA FOR CHANNEL "source_2";

要查看START REPLICA命令的完整语法和其他可用选项,请参见 Section 15.4.2.6, “START REPLICA Statement”。

要验证两个通道是否已启动并正常运行,您可以在副本上发出SHOW REPLICA STATUS语句,例如:

mysql> SHOW SLAVE STATUS FOR CHANNEL "source_1"\G
mysql> SHOW SLAVE STATUS FOR CHANNEL "source_2"\G
Or from MySQL 8.0.22:
mysql> SHOW REPLICA STATUS FOR CHANNEL "source_1"\G
mysql> SHOW REPLICA STATUS FOR CHANNEL "source_2"\G

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-stop-replica.html

19.1.5.6 停止多源复制

STOP REPLICA语句可用于停止多源复制。默认情况下,如果在多源复制上使用STOP REPLICA语句,则所有通道都会停止。可选择使用FOR CHANNEL *channel*子句仅停止特定通道。

  • 停止所有当前配置的复制通道:

    mysql> STOP SLAVE;
    Or from MySQL 8.0.22:
    mysql> STOP REPLICA;
    
  • 若要仅停止命名通道,请使用FOR CHANNEL *channel*子句:

    mysql> STOP SLAVE FOR CHANNEL "source_1";
    Or from MySQL 8.0.22:
    mysql> STOP REPLICA FOR CHANNEL "source_1";
    

有关STOP REPLICA命令的完整语法和其他可用选项,请参见 Section 15.4.2.8, “STOP REPLICA Statement”。

原文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-reset-replica.html

19.1.5.7 重置多源复制

RESET REPLICA语句可用于重置多源复制。默认情况下,如果在多源复制上使用RESET REPLICA语句,则会重置所有通道。可选择使用FOR CHANNEL *channel*子句仅重置特定通道。

  • 要重置当前配置的所有复制通道:

    mysql> RESET SLAVE;
    Or from MySQL 8.0.22:
    mysql> RESET REPLICA;
    
  • 要仅重置命名通道,请使用FOR CHANNEL *channel*子句:

    mysql> RESET SLAVE FOR CHANNEL "source_1";
    Or from MySQL 8.0.22:
    mysql> RESET REPLICA FOR CHANNEL "source_1";
    

对于基于 GTID 的复制,请注意RESET REPLICA对复制的 GTID 执行历史没有影响。如果要清除此内容,请在复制上发出RESET MASTER

RESET REPLICA使复制忘记其复制位置,并清除中继日志,但不会更改任何复制连接参数(如源主机名)或复制过滤器。如果要删除某个通道的这些内容,请发出RESET REPLICA ALL

有关RESET REPLICA命令的完整语法和其他可用选项,请参见 Section 15.4.2.4, “RESET REPLICA Statement”。

译文:dev.mysql.com/doc/refman/8.0/en/replication-multi-source-monitoring.html

19.1.5.8 监控多源复制

要监视复制通道的状态,存在以下选项:

  • 使用复制性能模式表。这些表的第一列是Channel_Name。这使您可以基于Channel_Name编写复杂查询。请参见第 29.12.11 节,“性能模式复制表”。

  • 使用SHOW REPLICA STATUS FOR CHANNEL *channel*。默认情况下,如果未使用FOR CHANNEL *channel*子句,则此语句将显示所有通道的复制状态,每个通道一行。标识符Channel_name将作为结果集中的一列添加。如果提供了FOR CHANNEL *channel*子句,则结果仅显示命名复制通道的状态。

注意

SHOW VARIABLES语句不适用于多个复制通道。通过这些变量可用的信息已迁移到复制性能表。在具有多个通道的拓扑中使用SHOW VARIABLES语句仅显示默认通道的状态。

启用多源复制时发出的错误代码和消息指定生成错误的通道。

19.1.5.8.1 使用性能模式表监视通道

本节解释了如何使用复制性能模式表监视通道。您可以选择监视所有通道或现有通道的子集。

要监视所有通道的连接状态:

mysql> SELECT * FROM replication_connection_status\G;
*************************** 1\. row ***************************
CHANNEL_NAME: source_1
GROUP_NAME:
SOURCE_UUID: 046e41f8-a223-11e4-a975-0811960cc264
THREAD_ID: 24
SERVICE_STATE: ON
COUNT_RECEIVED_HEARTBEATS: 0
LAST_HEARTBEAT_TIMESTAMP: 0000-00-00 00:00:00
RECEIVED_TRANSACTION_SET: 046e41f8-a223-11e4-a975-0811960cc264:4-37
LAST_ERROR_NUMBER: 0
LAST_ERROR_MESSAGE:
LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00
*************************** 2\. row ***************************
CHANNEL_NAME: source_2
GROUP_NAME:
SOURCE_UUID: 7475e474-a223-11e4-a978-0811960cc264
THREAD_ID: 26
SERVICE_STATE: ON
COUNT_RECEIVED_HEARTBEATS: 0
LAST_HEARTBEAT_TIMESTAMP: 0000-00-00 00:00:00
RECEIVED_TRANSACTION_SET: 7475e474-a223-11e4-a978-0811960cc264:4-6
LAST_ERROR_NUMBER: 0
LAST_ERROR_MESSAGE:
LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00 2 rows in set (0.00 sec)

在上述输出中,有两个启用的通道,如CHANNEL_NAME字段所示,它们分别称为source_1source_2

添加CHANNEL_NAME字段使您能够查询特定通道的性能模式表。要监视命名通道的连接状态,请使用WHERE CHANNEL_NAME=*channel*子句:

mysql> SELECT * FROM replication_connection_status WHERE CHANNEL_NAME='source_1'\G
*************************** 1\. row ***************************
CHANNEL_NAME: source_1
GROUP_NAME:
SOURCE_UUID: 046e41f8-a223-11e4-a975-0811960cc264
THREAD_ID: 24
SERVICE_STATE: ON
COUNT_RECEIVED_HEARTBEATS: 0
LAST_HEARTBEAT_TIMESTAMP: 0000-00-00 00:00:00
RECEIVED_TRANSACTION_SET: 046e41f8-a223-11e4-a975-0811960cc264:4-37
LAST_ERROR_NUMBER: 0
LAST_ERROR_MESSAGE:
LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00 1 row in set (0.00 sec)

同样,WHERE CHANNEL_NAME=*channel*子句可用于监视其他复制性能模式表以获取特定通道的信息。有关更多信息,请参见第 29.12.11 节,“性能模式复制表”。

19.1.6 复制和二进制日志选项和变量

原文:dev.mysql.com/doc/refman/8.0/en/replication-options.html

19.1.6.1 复制和二进制日志选项和变量参考

19.1.6.2 复制源选项和变量

19.1.6.3 副本服务器选项和变量

19.1.6.4 二进制日志选项和变量

19.1.6.5 全局事务 ID 系统变量

以下各节包含有关用于复制和控制二进制日志的mysqld选项和服务器变量的信息。用于源和副本的选项和变量分别进行了介绍,与二进制日志记录和全局事务标识符(GTID)相关的选项和变量也是如此。还包括一组快速参考表,提供有关这些选项和变量的基本信息。

特别重要的是server_id 系统变量。

命令行格式 --server-id=#
系统变量 server_id
范围 全局
动态
SET_VAR 提示适用
类型 整数
默认值 1
最小值 0
最大值 4294967295

此变量指定服务器 ID。server_id 默认设置为 1。服务器可以使用此默认 ID 启动,但是当启用二进制日志记录时,如果您没有显式设置server_id 来指定服务器 ID,则会发出信息消息。

对于用于复制拓扑的服务器,您必须为每个复制服务器指定一个唯一的服务器 ID,范围从 1 到 2³² − 1。“唯一”意味着每个 ID 必须与复制拓扑中任何其他源或副本正在使用的任何其他 ID 不同。有关更多信息,请参见第 19.1.6.2 节,“复制源选项和变量”,以及第 19.1.6.3 节,“副本服务器选项和变量”。

如果服务器 ID 设置为 0,则会进行二进制日志记录,但具有服务器 ID 0 的源会拒绝来自副本的任何连接,具有服务器 ID 0 的副本会拒绝连接到源。请注意,尽管您可以将服务器 ID 动态更改为非零值,但这样做并不会立即启用复制。您必须更改服务器 ID,然后重新启动服务器以初始化副本。

有关更多信息,请参见第 19.1.2.2 节,“设置复制配置”。

server_uuid

MySQL 服务器生成一个真正的 UUID,除了默认或用户提供的server_id系统变量设置之外。这作为全局只读变量server_uuid可用。

注意

server_uuid系统变量的存在不会改变为每个 MySQL 服务器设置唯一server_id值的要求,如本节前面描述的。

系统变量 server_uuid
范围 全局
动态
SET_VAR提示适用
类型 字符串

启动时,MySQL 服务器会自动获取 UUID,如���所示:

  1. 尝试读取并使用写入文件*data_dir*/auto.cnf中的 UUID(其中data_dir是服务器的数据目录)。

  2. 如果未找到*data_dir*/auto.cnf,则生成一个新的 UUID 并将其保存到此文件中,必要时创建该文件。

auto.cnf文件的格式类似于my.cnfmy.ini文件的格式。auto.cnf只有一个包含单个server_uuid设置和值的[auto]部分;文件的内容类似于这里显示的内容:

[auto]
server_uuid=8a94f357-aab4-11df-86ab-c80aa9429562

重要

auto.cnf文件是自动生成的;不要尝试编写或修改此文件。

在使用 MySQL 复制时,源和副本知道彼此的 UUID。副本的 UUID 值可以在SHOW REPLICAS的输出中看到(或在 MySQL 8.0.22 之前,在SHOW SLAVE HOSTS中)。一旦执行了START REPLICA,源的 UUID 值就可以在副本的SHOW REPLICA STATUS的输出中找到(在 MySQL 8.0.22 中,SLAVE关键字被REPLICA替换)。

注意

发出STOP REPLICARESET REPLICA语句不会重置在副本上使用的源 UUID。

服务器的server_uuid也用于 GTID 中在该服务器上发起的事务。有关更多信息,请参见第 19.1.3 节,“使用全局事务标识符进行复制”。

在启动时,如果复制 I/O(接收器)线程的源 UUID 等于自身 UUID,则会生成错误并中止,除非已设置--replicate-same-server-id选项。此外,如果以下任一情况为真,则复制接收器线程会生成警告:

  • 没有符合预期server_uuid的源存在。

  • 源的server_uuid已更改,尽管从未执行过CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句。

原文:dev.mysql.com/doc/refman/8.0/en/replication-options-reference.html

19.1.6.1 复制和二进制日志选项和变量参考

下面的两个部分提供了关于适用于复制和二进制日志的 MySQL 命令行选项和系统变量的基本信息。

复制选项和变量

下面列表中的命令行选项和系统变量与复制源服务器和副本相关。第 19.1.6.2 节,“复制源选项和变量” 提供了有关与复制源服务器相关的选项和变量的更详细信息。有关与副本相关的选项和变量的更多信息,请参见第 19.1.6.3 节,“副本服务器选项和变量”。

  • abort-slave-event-count: 用于 MySQL 测试的调试和复制测试的选项。

  • auto_increment_increment: AUTO_INCREMENT 列按此值递增。

  • auto_increment_offset: 添加到 AUTO_INCREMENT 列的偏移量。

  • Com_change_master: CHANGE REPLICATION SOURCE TO 和 CHANGE MASTER TO 语句的计数。

  • Com_change_replication_source: CHANGE REPLICATION SOURCE TO 和 CHANGE MASTER TO 语句的计数。

  • Com_replica_start: START REPLICA 和 START SLAVE 语句的计数。

  • Com_replica_stop: STOP REPLICA 和 STOP SLAVE 语句的计数。

  • Com_show_master_status: SHOW MASTER STATUS 语句的计数。

  • Com_show_replica_status: SHOW REPLICA STATUS 和 SHOW SLAVE STATUS 语句的计数。

  • Com_show_replicas: SHOW REPLICAS 和 SHOW SLAVE HOSTS 语句的计数。

  • Com_show_slave_hosts: SHOW REPLICAS 和 SHOW SLAVE HOSTS 语句的计数。

  • Com_show_slave_status: SHOW REPLICA STATUS 和 SHOW SLAVE STATUS 语句的计数。

  • Com_slave_start: START REPLICA 和 START SLAVE 语句的计数。

  • Com_slave_stop: STOP REPLICA 和 STOP SLAVE 语句的计数。

  • disconnect-slave-event-count: mysql-test 用于调试和测试复制的选项。

  • enforce_gtid_consistency: 防止无法以事务安全方式记录的语句执行。

  • expire_logs_days: 在多少天后清除二进制日志。

  • gtid_executed: 全局:二进制日志中的所有 GTID(全局)或当前事务(会话)中的所有 GTID。只读。

  • gtid_executed_compression_period: 每发生这么多次事务时压缩 gtid_executed 表。0 表示永远不压缩此表。仅在禁用二进制日志记录时适用。

  • gtid_mode: 控制是否启用基于 GTID 的日志记录以及事务日志可以包含的类型。

  • gtid_next: 指定后续事务或事务的 GTID;详细信息请参阅文档。

  • gtid_owned: 由此客户端(会话)或所有客户端拥有的 GTID 集合,以及所有者的线程 ID(全局)。只读。

  • gtid_purged: 已从二进制日志中清除的所有 GTID 集合。

  • immediate_server_version: 作为即时复制源的服务器的 MySQL 服务器发布号码。

  • init_replica: 当复制品连接到源时执行的语句。

  • init_slave: 当复制品连接到源时执行的语句。

  • log_bin_trust_function_creators: 如果等于 0(默认值),则在使用--log-bin 时,只允许具有 SUPER 特权的用户创建存储函数,并且只有创建的函数不会破坏二进制日志记录时才允许。

  • log_statements_unsafe_for_binlog: 禁用写入错误日志中的错误 1592 警告。

  • master-info-file: 记住源和 I/O 复制线程在源二进制日志中的位置的文件的位置和名称。

  • master-retry-count: 在放弃之前,复制品尝试连接到源的次数。

  • master_info_repository: 是否将包含源信息和复制 I/O 线程位置在源二进制日志中的连接元数据存储库写入文件或表。

  • max_relay_log_size: 如果非零,则中继日志在其大小超过此值时会自动旋转。如果为零,则旋转发生的大小由 max_binlog_size 的值确定。

  • original_commit_timestamp: 事务在原始源上提交时的时间。

  • original_server_version: 事务最初提交的服务器的 MySQL 服务器发布号。

  • relay_log: 用于中继日志的位置和基本名称。

  • relay_log_basename: 中继日志的完整路径,包括文件名。

  • relay_log_index: 用于保存最后中继日志列表的文件的位置和名称。

  • relay_log_info_file: 用于复制记录有关中继日志信息的应用程序元数据存储库的文件名。

  • relay_log_info_repository: 是否将复制 SQL 线程在中继日志中的位置写入文件或表。

  • relay_log_purge: 确定是否清除中继日志。

  • relay_log_recovery: 是否启用在启动时从源自动恢复中继日志文件;必须为崩溃安全的复制启用。

  • relay_log_space_limit: 用于所有中继日志的最大空间。

  • replica_checkpoint_group: 多线程复制在调用检查点操作更新进度状态之前处理的最大事务数。不支持 NDB 集群。

  • replica_checkpoint_period: 在此毫秒数后更新多线程复制的进度状态并将中继日志信息刷新到磁盘。不支持 NDB 集群。

  • replica_compressed_protocol: 使用源/复制协议��压缩。

  • replica_exec_mode: 允许在幂等模式(键和一些其他错误被抑制)和严格模式之间切换复制线程;严格模式是默认的,除了 NDB 集群,那里始终使用幂等模式。

  • replica_load_tmpdir: 复制 LOAD DATA 语句时,复制品应将其临时文件放置的位置。

  • replica_max_allowed_packet: 从���制源服务器发送到复制品的数据包的最大大小(以字节为单位);覆盖 max_allowed_packet。

  • replica_net_timeout: 从源/复制连接中等待更多数据的秒数,然后中止读取。

  • Replica_open_temp_tables: 复制 SQL 线程当前打开的临时表数。

  • replica_parallel_type: 告诉复制品使用时间戳信息(LOGICAL_CLOCK)或数据库分区(DATABASE)来并行化事务。

  • replica_parallel_workers: 用于执行复制事务的应用程序线程数;当此值为 0 或 1 时,只有一个应用程序线程。NDB 集群:请参阅文档。

  • replica_pending_jobs_size_max: 持有尚未应用的事件的复制工作者队列的最大大小。

  • replica_preserve_commit_order: 确保复制工作者的所有提交按照源上的顺序发生,以在使用并行应用程序线程时保持一致性。

  • Replica_rows_last_search_algorithm_used: 此复制品最近用于定位行以进行基于行的复制(索引、表或哈希扫描)的搜索算法。

  • replica_skip_errors: 告诉复制线程在查询从提供的列表返回错误时继续复制。

  • replica_transaction_retries: 在事务由于死锁或经过的锁等待超时而失败时,复制 SQL 线程重试事务的次数,然后放弃并停止。

  • replica_type_conversions: 控制复制品上的类型转换模式。值是此列表中零个或多个元素的列表:ALL_LOSSY、ALL_NON_LOSSY。设置为空字符串以禁止源和复制品之间的类型转换。

  • replicate-do-db: 告诉复制 SQL 线程将复制限制在指定数据库中。

  • replicate-do-table: 告诉复制 SQL 线程将复制限制在指定表中。

  • replicate-ignore-db: 告诉复制 SQL 线程不要复制到指定数据库。

  • replicate-ignore-table: 告诉复制 SQL 线程不要复制到指定表。

  • replicate-rewrite-db: 更新具有与原始名称不同的数据库。

  • replicate-same-server-id: 在复制中,如果启用,则不跳过具有我们服务器 ID 的事件。

  • replicate-wild-do-table: 告诉复制 SQL 线程将复制限制在与指定通配符模式匹配的表中。

  • replicate-wild-ignore-table: 告诉复制 SQL 线程不要复制与给定通配符模式匹配的表。

  • replication_optimize_for_static_plugin_config: 针对静态插件配置的共享锁。

  • replication_sender_observe_commit_only: 半同步复制的有限回调。

  • report_host: 副本的主机名或 IP 地址,在副本注册期间报告给源。

  • report_password: 副本服务器应向源报告的任意密码;与用于复制用户帐户的密码不同。

  • report_port: 连接到副本并在副本注册期间向源报告的端口。

  • report_user: 副本服务器应向源报告的任意用户名;与用于复制用户帐户的名称不同。

  • rpl_read_size: 设置从二进制日志文件和中继日志文件中读取的最小数据量(以字节为单位)。

  • Rpl_semi_sync_master_clients: 半同步副本的数量。

  • rpl_semi_sync_master_enabled: 源上是否启用了半同步复制。

  • Rpl_semi_sync_master_net_avg_wait_time: 源等待来自副本回复的平均时间。

  • Rpl_semi_sync_master_net_wait_time: 源等待来自副本回复的总时间。

  • Rpl_semi_sync_master_net_waits: 源端等待来自副本的回复的总次数。

  • Rpl_semi_sync_master_no_times: 源端关闭半同步复制的次数。

  • Rpl_semi_sync_master_no_tx: 未成功确认的提交次数。

  • Rpl_semi_sync_master_status: 源端是否正在运行半同步复制。

  • Rpl_semi_sync_master_timefunc_failures: 调用时间函数时源端失败的次数。

  • rpl_semi_sync_master_timeout: 等待副本确认的毫秒数。

  • rpl_semi_sync_master_trace_level: 源端上的半同步复制调试跟踪级别。

  • Rpl_semi_sync_master_tx_avg_wait_time: 源端等待每个事务的平均时间。

  • Rpl_semi_sync_master_tx_wait_time: 源端等待事务的总时间。

  • Rpl_semi_sync_master_tx_waits: 源端等待事务的总次数。

  • rpl_semi_sync_master_wait_for_slave_count: 源端在继续之前必须收到每个事务的副本确认数。

  • rpl_semi_sync_master_wait_no_slave: 即使没有副本,源端是否等待超时。

  • rpl_semi_sync_master_wait_point: 副本事务接收确认的等待点。

  • Rpl_semi_sync_master_wait_pos_backtraverse: 源端等待具有比先前等待的事件更低的二进制坐标的事件的总次数。

  • Rpl_semi_sync_master_wait_sessions: 当前正在等待副本回复的会话数。

  • Rpl_semi_sync_master_yes_tx: 成功确认的提交次数。

  • rpl_semi_sync_replica_enabled: 副本上是否启用了半同步复制。

  • Rpl_semi_sync_replica_status: 复制端是否正在运行半同步复制。

  • rpl_semi_sync_replica_trace_level: 复制端半同步复制的调试跟踪级别。

  • rpl_semi_sync_slave_enabled: 复制端是否启用半同步复制。

  • Rpl_semi_sync_slave_status: 复制端是否正在运行半同步复制。

  • rpl_semi_sync_slave_trace_level: 复制端半同步复制的调试跟踪级别。

  • Rpl_semi_sync_source_clients: 半同步复制的复制端数量。

  • rpl_semi_sync_source_enabled: 源端是否启用半同步复制。

  • Rpl_semi_sync_source_net_avg_wait_time: 源端等待来自复制端回复的平均时间。

  • Rpl_semi_sync_source_net_wait_time: 源端等待复制端回复的总时间。

  • Rpl_semi_sync_source_net_waits: 源端等待复制端回复的总次数。

  • Rpl_semi_sync_source_no_times: 源端关闭半同步复制的次数。

  • Rpl_semi_sync_source_no_tx: 未成功确认的提交次数。

  • Rpl_semi_sync_source_status: 源端是否正在运行半同步复制。

  • Rpl_semi_sync_source_timefunc_failures: 调用时间函数时源端失败的次数。

  • rpl_semi_sync_source_timeout: 等待复制端确认的毫秒数。

  • rpl_semi_sync_source_trace_level: 源端半同步复制的调试跟踪级别。

  • Rpl_semi_sync_source_tx_avg_wait_time: 源端等待每个事务的平均时间。

  • Rpl_semi_sync_source_tx_wait_time: 源端等待事务的总时间。

  • Rpl_semi_sync_source_tx_waits: 源等待事务的总次数。

  • rpl_semi_sync_source_wait_for_replica_count: 在继续之前,源必须在每个事务中收到的副本确认数。

  • rpl_semi_sync_source_wait_no_replica: 源是否在没有副本的情况下等待超时。

  • rpl_semi_sync_source_wait_point: 等待副本事务接收确认的等待点���

  • Rpl_semi_sync_source_wait_pos_backtraverse: 源等待具有比先前等待的事件更低的二进制坐标的事件的总次数。

  • Rpl_semi_sync_source_wait_sessions: 当前正在等待副本回复的会话数。

  • Rpl_semi_sync_source_yes_tx: 成功确认的提交次数。

  • rpl_stop_replica_timeout: STOP REPLICA 等待超时的秒数。

  • rpl_stop_slave_timeout: STOP REPLICA 或 STOP SLAVE 等待超时的秒数。

  • server_uuid: 服务器的全局唯一 ID,在服务器启动时自动生成。

  • show-replica-auth-info: 在此源上的 SHOW REPLICAS 中显示用户名和密码。

  • show-slave-auth-info: 在此源上的 SHOW REPLICAS 和 SHOW SLAVE HOSTS 中显示用户名和密码。

  • skip-replica-start: 如果设置,当副本服务器启动时不会自动启动复制。

  • skip-slave-start: 如果设置,当副本服务器启动时不会自动启动复制。

  • slave-skip-errors: 当查询从提供的列表返回错误时,告诉复制线程继续复制。

  • slave_checkpoint_group: 多线程副本处理的最大事务数,在调用检查点操作以更新进度状态之前。不受 NDB Cluster 支持。

  • slave_checkpoint_period: 在此毫秒数后更新多线程副本的进度状态并将中继日志信息刷新到磁盘。NDB Cluster 不支持。

  • slave_compressed_protocol: 使用源/副本协议的压缩。

  • slave_exec_mode: 允许在IDEMPOTENT模式(键和一些其他错误被抑制)和STRICT模式之间切换复制线程;STRICT模式是默认的,除了 NDB Cluster,始终使用IDEMPOTENT

  • slave_load_tmpdir: 当复制LOAD DATA语句时,副本应将临时文件放置的位置。

  • slave_max_allowed_packet: 从复制源服务器发送到副本的数据包的最大大小(以字节为单位);覆盖max_allowed_packet

  • slave_net_timeout: 等待源/副本连接中更多数据的秒数,超时前中止读取。

  • Slave_open_temp_tables: 复制 SQL 线程当前打开的临时表数。

  • slave_parallel_type: 告诉副本使用时间戳信息(LOGICAL_CLOCK)或数据库分区(DATABASE)来并行化事务。

  • slave_parallel_workers: 用于并行执行复制事务的应用程序线程数;0 或 1 禁用副本多线程。NDB Cluster:请参阅文档。

  • slave_pending_jobs_size_max: 持有尚未应用的事件的副本工作线程队列的最大大小。

  • slave_preserve_commit_order: 确保副本工作线程的所有提交按照源上的顺序发生,以保持一致性,当使用并行应用程序线程时。

  • Slave_rows_last_search_algorithm_used: 此副本最近用于定位行以进行基于行的复制(索引、表或哈希扫描)的搜索算法。

  • slave_rows_search_algorithms: 确定用于副本更新批处理的搜索算法。从此列表中选择任意 2 或 3 个:INDEX_SEARCH、TABLE_SCAN、HASH_SCAN。

  • slave_transaction_retries: 在复制 SQL 线程在死锁或经过的锁等待超时失败的情况下,重试事务的次数,然后放弃并停止。

  • slave_type_conversions: 控制副本上的类型转换模式。 值是以下列表中的零个或多个元素:ALL_LOSSY,ALL_NON_LOSSY。 将其设置为空字符串以禁止源和副本之间的类型转换。

  • sql_log_bin: 控制当前会话的二进制日志记录。

  • sql_replica_skip_counter: 副本应跳过的源事件数。 与 GTID 复制不兼容。

  • sql_slave_skip_counter: 副本应跳过的源事件数。 与 GTID 复制不兼容。

  • sync_master_info: 每第#个事件后同步源信息。

  • sync_relay_log: 每第#个事件后将 relay 日志同步到磁盘。

  • sync_relay_log_info: 每第#个事件后将 relay.info 文件同步到磁盘。

  • sync_source_info: 每第#个事件后同步源信息。

  • terminology_use_previous: 在不兼容更改的版本之前使用术语。

  • transaction_write_set_extraction: 定义在事务期间提取的写入哈希的算法。

对于所有与mysqld一起使用的命令行选项、系统变量和状态变量的列表,请参阅 Section 7.1.4, “Server Option, System Variable, and Status Variable Reference”。

二进制日志选项和变量

以下列表中的命令行选项和系统变量与二进制日志相关。 Section 19.1.6.4, “Binary Logging Options and Variables”提供了有关与二进制日志相关的选项和变量的更详细信息。 有关二进制日志的其他一般信息,请参阅 Section 7.4.4, “The Binary Log”。

  • binlog-checksum: 启用或禁用二进制日志校验和。

  • binlog-do-db: 限制二进制日志记录到特定数据库。

  • binlog-ignore-db: 告诉源不要将对给定数据库的更新写入二进制日志。

  • binlog-row-event-max-size: 二进制日志最大事件大小。

  • Binlog_cache_disk_use: 使用临时文件而不是二进制日志缓存的事务数。

  • binlog_cache_size: 在事务期间保存 SQL 语句以用于二进制日志的缓存大小。

  • Binlog_cache_use: 使用临时二进制日志缓存的事务数。

  • binlog_checksum: 启用或禁用二进制日志校验和。

  • binlog_direct_non_transactional_updates: 导致使用语句格式对非事务引擎进行的更新直接写入二进制日志。在使用之前请查看文档。

  • binlog_encryption: 在此服务器上为二进制日志文件和中继日志文件启用加密。

  • binlog_error_action: 控制服务器无法写入二进制日志时会发生什么。

  • binlog_expire_logs_auto_purge: 控制二进制日志文件的自动清理;当启用时,可以通过将 binlog_expire_logs_seconds 和 expire_logs_days 都设置为 0 来覆盖。

  • binlog_expire_logs_seconds: 在这么多秒后清理二进制日志。

  • binlog_format: 指定二进制日志的格式。

  • binlog_group_commit_sync_delay: 设置在将事务同步到磁盘之前等待的微秒数。

  • binlog_group_commit_sync_no_delay_count: 设置在中止由 binlog_group_commit_sync_delay 指定的当前延迟之前等待的最大事务数。

  • binlog_gtid_simple_recovery: 控制在 GTID 恢复期间如何迭代二进制日志。

  • binlog_max_flush_queue_time: 在刷新到二进制日志之前读取事务的时间。

  • binlog_order_commits: 是否按照写入二进制日志的顺序提交。

  • binlog_rotate_encryption_master_key_at_startup: 在服务器启动时旋转二进制日志主密钥。

  • binlog_row_image: 记录行更改时使用完整或最小图像。

  • binlog_row_metadata: 在使用基于行的日志记录时,记录所有或仅最小的与表相关的元数据到二进制日志中。

  • binlog_row_value_options: 启用基于行复制的部分 JSON 更新的二进制日志记录。

  • binlog_rows_query_log_events: 启用时,在使用基于行的日志记录时启用行查询日志事件的记录。默认情况下禁用。在为早于 5.6 版本的副本/读取器生成日志时不要启用。

  • Binlog_stmt_cache_disk_use: 使用临时文件而不是二进制日志语句缓存的非事务语句数量。

  • binlog_stmt_cache_size: 在事务期间为二进制日志保留非事务语句的缓存大小。

  • Binlog_stmt_cache_use: 使用临时二进制日志语句缓存的语句数量。

  • binlog_transaction_compression: 启用二进制日志文件中事务负载的压缩。

  • binlog_transaction_compression_level_zstd: 二进制日志文件中事务负载的压缩级别。

  • binlog_transaction_dependency_history_size: 用于查找最后更新某行的事务的行哈希数量。

  • binlog_transaction_dependency_tracking: 用于评估哪些事务可以由副本的多线程应用程序并行执行的依赖信息来源(提交时间戳或事务写入集)。

  • Com_show_binlog_events: SHOW BINLOG EVENTS 语句的计数。

  • Com_show_binlogs: SHOW BINLOGS 语句的计数。

  • log-bin: 二进制日志文件的基本名称。

  • log-bin-index: 二进制日志索引文件的名称。

  • log_bin: 是否启用二进制日志。

  • log_bin_basename: 二进制日志文件的路径和基本名称。

  • log_bin_use_v1_row_events: 服务器是否使用版本 1 的二进制日志行事件。

  • log_replica_updates: 副本是否应将其复制 SQL 线程执行的更新记录到自己的二进制日志中。

  • log_slave_updates: 副本是否应将其复制 SQL 线程执行的更新记录到自己的二进制日志中。

  • master_verify_checksum: 使源在从二进制日志读取时检查校验和。

  • max-binlog-dump-events: mysql-test 用于调试和测试复制的选项。

  • max_binlog_cache_size: 可用于限制用于缓存多语句事务的总字节大小。

  • max_binlog_size: 当大小超过此值时,二进制日志会自动轮换。

  • max_binlog_stmt_cache_size: 可用于限制在事务期间缓存所有非事务语句的总大小。

  • replica_sql_verify_checksum: 使副本在从中继日志读取时检查校验和。

  • slave-sql-verify-checksum: 使副本在从中继日志读取时检查校验和。

  • slave_sql_verify_checksum: 使副本在从中继日志读取时检查校验和。

  • source_verify_checksum: 使源在从二进制日志读取时检查校验和。

  • sporadic-binlog-dump-fail: mysql-test 用于调试和测试复制的选项。

  • sync_binlog: 每第#个事件后将二进制日志同步刷新到磁盘。

对于所有与mysqld一起使用的命令行选项、系统和状态变量的列表,请参见第 7.1.4 节,“服务器选项、系统变量和状态变量参考”。

原文:dev.mysql.com/doc/refman/8.0/en/replication-options-source.html

19.1.6.2 复制源选项和变量

本节描述了您可以在复制源服务器上使用的服务器选项和系统变量。您可以在命令行或选项文件中指定选项。您可以使用 SET 指定系统变量值。

在源和每个副本上,您必须设置 server_id 系统变量以建立唯一的复制 ID。对于每个服务器,您应该选择一个在 1 到 2³² − 1 范围内的唯一正整数,并且每个 ID 必须与复制拓扑中任何其他源或副本使用的任何其他 ID 不同。例如:server-id=3

用于控制二进制日志记录的源上使用的选项,请参阅第 19.1.6.4 节,“二进制日志选项和变量”。

复制源服务器的启动选项

以下列表描述了用于控制复制源服务器的启动选项。复制相关的系统变量将在本节后面讨论。

  • --show-replica-auth-info

    命令行格式 --show-replica-auth-info[={OFF&#124;ON}]
    引入版本 8.0.26
    类型 布尔
    默认值 OFF

    从 MySQL 8.0.26 开始,请使用 --show-replica-auth-info,在 MySQL 8.0.26 之前,请使用 --show-slave-auth-info。这两个选项具有相同的效果。这些选项在源上显示复制用户名和密码在 SHOW REPLICAS(或在 MySQL 8.0.22 之前,SHOW SLAVE HOSTS)的输出中,用于使用 --report-user--report-password 选项启动的副本。

  • --show-slave-auth-info

    命令行格式 --show-slave-auth-info[={OFF&#124;ON}]
    已弃用 8.0.26
    类型 布尔
    默认值 OFF

    在 MySQL 8.0.26 之前,请使用此选项,而不是 --show-replica-auth-info。这两个选项具有相同的效果。

复制源服务器上使用的系统变量

以下系统变量用于或由复制源服务器使用:

  • auto_increment_increment

    命令行格式 --auto-increment-increment=#
    系统变量 auto_increment_increment
    范围 全局,会话
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 1
    最小值 1
    最大值 65535

    auto_increment_incrementauto_increment_offset 用于循环(源到源)复制,并可用于控制 AUTO_INCREMENT 列的操作。这两个变量都有全局和会话值,每个变量的值都可以是介于 1 到 65,535 之间的整数。将这两个变量中的任何一个的值设置为 0 会使其值改为 1。尝试将这两个变量中的任何一个的值设置为大于 65,535 或小于 0 的整数会使其值改为 65,535。尝试将 auto_increment_incrementauto_increment_offset 的值设置为非整数值会产生错误,并且变量的实际值保持不变。

    注意

    auto_increment_increment 也支持用于 NDB 表。

    截至 MySQL 8.0.18,设置此系统变量的会话值不再是受限制的操作。

    当在服务器上启动组复制时,auto_increment_increment 的值会更改为 group_replication_auto_increment_increment 的值,默认为 7,并且 auto_increment_offset 的值会更改为服务器 ID。当停止组复制时,这些更改会被还原。只有当 auto_increment_incrementauto_increment_offset 的默认值都为 1 时,才会进行这些更改和还原。如果它们的值已经从默认值修改过,则组复制不会更改它们。从 MySQL 8.0 开始,当组复制处于单主模式时,即只有一个服务器写入时,系统变量也不会被修改。

    auto_increment_incrementauto_increment_offset影响AUTO_INCREMENT列的行为如下:

    • auto_increment_increment控制连续列值之间的间隔。例如:

      mysql> SHOW VARIABLES LIKE 'auto_inc%';
      +--------------------------+-------+
      | Variable_name            | Value |
      +--------------------------+-------+
      | auto_increment_increment | 1     |
      | auto_increment_offset    | 1     |
      +--------------------------+-------+
      2 rows in set (0.00 sec)
      
      mysql> CREATE TABLE autoinc1
       -> (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
        Query OK, 0 rows affected (0.04 sec)
      
      mysql> SET @@auto_increment_increment=10;
      Query OK, 0 rows affected (0.00 sec)
      
      mysql> SHOW VARIABLES LIKE 'auto_inc%';
      +--------------------------+-------+
      | Variable_name            | Value |
      +--------------------------+-------+
      | auto_increment_increment | 10    |
      | auto_increment_offset    | 1     |
      +--------------------------+-------+
      2 rows in set (0.01 sec)
      
      mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
      Query OK, 4 rows affected (0.00 sec)
      Records: 4  Duplicates: 0  Warnings: 0
      
      mysql> SELECT col FROM autoinc1;
      +-----+
      | col |
      +-----+
      |   1 |
      |  11 |
      |  21 |
      |  31 |
      +-----+
      4 rows in set (0.00 sec)
      
    • auto_increment_offset确定AUTO_INCREMENT列值的起始点。考虑以下情况,假设这些语句在与auto_increment_increment描述中给出的示例相同的会话中执行:

      mysql> SET @@auto_increment_offset=5;
      Query OK, 0 rows affected (0.00 sec)
      
      mysql> SHOW VARIABLES LIKE 'auto_inc%';
      +--------------------------+-------+
      | Variable_name            | Value |
      +--------------------------+-------+
      | auto_increment_increment | 10    |
      | auto_increment_offset    | 5     |
      +--------------------------+-------+
      2 rows in set (0.00 sec)
      
      mysql> CREATE TABLE autoinc2
       -> (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
      Query OK, 0 rows affected (0.06 sec)
      
      mysql> INSERT INTO autoinc2 VALUES (NULL), (NULL), (NULL), (NULL);
      Query OK, 4 rows affected (0.00 sec)
      Records: 4  Duplicates: 0  Warnings: 0
      
      mysql> SELECT col FROM autoinc2;
      +-----+
      | col |
      +-----+
      |   5 |
      |  15 |
      |  25 |
      |  35 |
      +-----+
      4 rows in set (0.02 sec)
      

      auto_increment_offset的值大于auto_increment_increment的值时,将忽略auto_increment_offset的值。

    如果这两个变量中的任何一个被更改,然后新行被插入到包含AUTO_INCREMENT列的表中,结果可能看起来令人费解,因为AUTO_INCREMENT值的系列是在不考虑列中已经存在的任何值的情况下计算的,并且插入的下一个值是系列中大于AUTO_INCREMENT列中最大现有值的最小值。该系列的计算方式如下:

    auto_increment_offset + N × auto_increment_increment

    其中N是系列[1, 2, 3, ...]中的正整数值。例如:

    mysql> SHOW VARIABLES LIKE 'auto_inc%';
    +--------------------------+-------+
    | Variable_name            | Value |
    +--------------------------+-------+
    | auto_increment_increment | 10    |
    | auto_increment_offset    | 5     |
    +--------------------------+-------+
    2 rows in set (0.00 sec)
    
    mysql> SELECT col FROM autoinc1;
    +-----+
    | col |
    +-----+
    |   1 |
    |  11 |
    |  21 |
    |  31 |
    +-----+
    4 rows in set (0.00 sec)
    
    mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
    Query OK, 4 rows affected (0.00 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> SELECT col FROM autoinc1;
    +-----+
    | col |
    +-----+
    |   1 |
    |  11 |
    |  21 |
    |  31 |
    |  35 |
    |  45 |
    |  55 |
    |  65 |
    +-----+
    8 rows in set (0.00 sec)
    

    所示的auto_increment_incrementauto_increment_offset的值生成系列 5 + N × 10,即[5, 15, 25, 35, 45, ...]。在INSERT之前col列中存在的最高值为 31,AUTO_INCREMENT系列中的下一个可用值为 35,因此col的插入值从该点开始,并且查询的结果如SELECT中所示。

    不可能将这两个变量的影响限制在单个表中;这些变量控制 MySQL 服务器上所有表中的所有AUTO_INCREMENT列的行为。如果设置了任一变量的全局值,则其影响将持续,直到更改全局值或通过设置会话值覆盖,或者直到mysqld被重新启动。如果设置了本地值,则新值会影响当前用户在会话期间插入新行的所有表的AUTO_INCREMENT列,除非在该会话期间更改了这些值。

    auto_increment_increment的默认值为 1。请参阅第 19.5.1.1 节,“复制和 AUTO_INCREMENT”。

  • auto_increment_offset

    命令行格式 --auto-increment-offset=#
    系统变量 auto_increment_offset
    作用范围 全局,会话
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 1
    最小值 1
    最大值 65535

    此变量的默认值为 1。如果将其保留为默认值,并且在多主模式下在服务器上启动组复制,则将其更改为服务器 ID。有关更多信息,请参阅auto_increment_increment的描述。

    注意

    auto_increment_offset 也支持用于与NDB表。

    截至 MySQL 8.0.18,设置此系统变量的会话值不再是受限制的操作。

  • immediate_server_version

    引入版本 8.0.14
    系统变量 immediate_server_version
    作用范围 会话
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 999999
    最小值 0
    最大值 999999

    用于复制的内部使用。此会话系统变量保存了复制拓扑中作为直接源的 MySQL 服务器发布号(例如,MySQL 8.0.14 服务器实例的80014)。如果此直接服务器处于不支持会话系统变量的发布中,则变量的值设置为 0(UNKNOWN_SERVER_VERSION)。

    此变量的值从源复制到副本。有了这些信息,副本可以正确处理源自较旧发布的源的数据,通过识别在涉及的发布之间发生的语法更改或语义更改,并适当处理这些更改。此信息还可用于组复制环境,其中一个或多个复制组成员的发布版本比其他成员新。变量的值可以在每个事务的二进制日志中查看(作为Gtid_log_event的一部分,或者如果服务器上未使用 GTID,则作为Anonymous_gtid_log_event),并且在调试跨版本复制问题时可能会有所帮助。

    设置此系统变量的会话值是受限制的操作。会话用户必须具有REPLICATION_APPLIER权限(请参阅第 19.3.3 节,“复制权限检查”),或具有足够权限设置受限制会话变量的权限(请参阅第 7.1.9.1 节,“系统变量权限”)。但是,请注意,该变量不是供用户设置的;它是由复制基础设施自动设置的。

  • original_server_version

    引入版本 8.0.14
    系统变量 original_server_version
    范围 会话
    动态
    SET_VAR提示适用
    类型 整数
    默认值 999999
    最小值 0
    最大值 999999

    用于复制的内部使用。此会话系统变量保存了事务最初提交的 MySQL Server 版本号(例如,对于 MySQL 8.0.14 服务器实例,为80014)。如果此原始服务器的版本不支持会话系统变量,则变量的值将设置为 0(UNKNOWN_SERVER_VERSION)。请注意,当原始服务器设置了版本号时,如果立即服务器或复制拓扑中的任何其他中介服务器不支持会话系统变量,则变量的值将重置为 0,并且不会复制其值。

    该变量的值设置和使用方式与immediate_server_version系统变量相同。如果变量的值与immediate_server_version系统变量的值相同,则只记录后者在二进制日志中,并指示原始服务器版本相同。

    在 Group Replication 环境中,查看更改日志事件,这些事件是每个组成员在新成员加入组时排队的特殊事务,都带有排队事务的组成员的服务器版本标记。这确保了加入成员知道原始捐赠者的服务器版本。因为特定视图更改的排队事件在所有成员上具有相同的 GTID,所以在这种情况下,相同的 GTID 实例可能具有不同的原始服务器版本。

    设置此系统变量的会话值是受限制的操作。会话用户必须具有REPLICATION_APPLIER权限(参见第 19.3.3 节,“复制权限检查”),或具有足够权限设置受限制会话变量的权限(参见第 7.1.9.1 节,“系统变量权限”)。但是,请注意,该变量不是供用户设置的;它是由复制基础设施自动设置的。

  • rpl_semi_sync_master_enabled

    命令行格式 --rpl-semi-sync-master-enabled[={OFF&#124;ON}]
    系统变量 rpl_semi_sync_master_enabled
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    控制源服务器上是否启用半同步复制。要启用或禁用插件,请将此变量设置为ONOFF(或分别为 1 或 0)。默认值为OFF

    仅当源端半同步复制插件已安装��才可用。

  • rpl_semi_sync_master_timeout

    命令行格式 --rpl-semi-sync-master-timeout=#
    系统变量 rpl_semi_sync_master_timeout
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 10000
    最小值 0
    最大值 4294967295
    单位 毫秒

    以毫秒为单位的值,控制源在提交等待来自副本的确认之前超时并回滚到异步复制的时间。默认值为 10000(10 秒)。

    仅当源端半同步复制插件已安装时才可用。

  • rpl_semi_sync_master_trace_level

    命令行格式 --rpl-semi-sync-master-trace-level=#
    系统变量 rpl_semi_sync_master_trace_level
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 32
    最小值 0
    最大值 4294967295

    源服务器上的半同步复制调试跟踪级别。定义了四个级别:

    • 1 = 一般级别(例如,时间函数失败)

    • 16 = 详细级别(更详细的信息)

    • 32 = 网络等待级别(有关网络等待的更多信息)

    • 64 = 函数级别(有关函数进入和退出的信息)

    仅当源端半同步复制插件已安装时才可用此变量。

  • rpl_semi_sync_master_wait_for_slave_count

    命令行格式 --rpl-semi-sync-master-wait-for-slave-count=#
    系统变量 rpl_semi_sync_master_wait_for_slave_count
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 1
    最小值 1
    最大值 65535

    源必须在继续之前每个事务收到的副本确认数。默认情况下,rpl_semi_sync_master_wait_for_slave_count1,这意味着在收到单个副本确认后,半同步复制会继续进行。对于此变量的小值性能最佳。

    例如,如果rpl_semi_sync_master_wait_for_slave_count2,则在超时期限配置为rpl_semi_sync_master_timeout之前,必须有 2 个副本确认接收事务,半同步复制才能继续。如果在超时期间较少的副本确认接收事务,则源会恢复到正常复制。

    注意

    此行为还取决于rpl_semi_sync_master_wait_no_slave

    仅当源端半同步复制插件已安装时才可用此变量。

  • rpl_semi_sync_master_wait_no_slave

    命令行格式 --rpl-semi-sync-master-wait-no-slave[={OFF&#124;ON}]
    系统变量 rpl_semi_sync_master_wait_no_slave
    范围 全局
    动态
    SET_VAR提示适用
    类型 布尔值
    默认值 ON

    控制源是否等待由rpl_semi_sync_master_timeout配置的超时期限到期,即使在超时期间副本计数降至少于rpl_semi_sync_master_wait_for_slave_count配置的副本数。

    rpl_semi_sync_master_wait_no_slave的值为ON(默认)时,在超时期间允许副本计数降至少于rpl_semi_sync_master_wait_for_slave_count。只要足够多的副本在超时期限到期之前确认事务,半同步复制就会继续。

    rpl_semi_sync_master_wait_no_slave的值为OFF时,如果在任何时候副本计数降至少于rpl_semi_sync_master_wait_for_slave_count中配置的数量,在由rpl_semi_sync_master_timeout配置的超时期间内,源将恢复到正常复制。

    此变量仅在安装了源端半同步复制插件时才可用。

  • rpl_semi_sync_master_wait_point

    命令行格式 --rpl-semi-sync-master-wait-point=value
    系统变量 rpl_semi_sync_master_wait_point
    范围 全局
    动态
    SET_VAR提示适用
    类型 枚举
    默认数值 AFTER_SYNC
    有效数值 AFTER_SYNC``AFTER_COMMIT

    此变量控制半同步复制源服务器在向提交事务的客户端返回状态之前等待副本确认接收事务的点。这些值是允许的:

    • AFTER_SYNC(默认):源将每个事务写入其二进制日志和副本,并将二进制日志同步到磁盘。源在同步后等待副本确认接收事务。在收到确认后,源将事务提交给存储引擎并向客户端返回结果,然后客户端可以继续。

    • AFTER_COMMIT:源将每个事务写入其二进制日志和副本,同步二进制日志,并提交事务给存储引擎。源在提交后等待副本确认接收事务。在收到确认后,源向客户端返回结果,然后客户端可以继续。

    这些设置的复制特性有以下不同:

    • 使用AFTER_SYNC,所有客户端同时看到已提交的事务:在副本确认并在源上提交给存储引擎之后。因此,所有客户端在源上看到相同的数据。

      在源故障的情况下,所有在源上提交的事务都已复制到副本(保存到其中继日志)。源服务器意外退出并故障转移至副本是无损的,因为副本是最新的。但请注意,在这种情况下源服务器不能重新启动,必须被丢弃,因为其二进制日志可能包含未提交的事务,在二进制日志恢复后在外部化后会与副本发生冲突。

    • 使用 AFTER_COMMIT,发出事务的客户端只有在服务器提交给存储引擎并接收到副本确认后才会收到返回状态。在提交之后和副本确认之前,其他客户端可能会在提交客户端之前看到已提交的事务。

      如果出现问题导致副本未能处理事务,则在源服务器意外退出并故障转移至副本时,这些客户端可能会看到相对于在源服务器上看到的数据有所丢失。

    仅当源端半同步复制插件已安装时才可用此变量。

    在 MySQL 5.7 中添加了 rpl_semi_sync_master_wait_point 后,由于它增加了半同步接口版本,创建了一个版本兼容性约束:MySQL 5.7 及更高版本的服务器不与旧版本的半同步复制插件一起工作,反之亦然。

  • rpl_semi_sync_source_enabled

    命令行格式 --rpl-semi-sync-source-enabled[={OFF&#124;ON}]
    引入版本 8.0.26
    系统变量 rpl_semi_sync_source_enabled
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    当在副本上安装了 rpl_semi_sync_sourcesemisync_source.so库)插件以设置半同步复制时,rpl_semi_sync_source_enabled 可用。如果安装了 rpl_semi_sync_master 插件(semisync_master.so库),则可用 rpl_semi_sync_master_enabled

    rpl_semi_sync_source_enabled 控制源服务器上是否启用半同步复制。要启用或禁用插件,请将此变量设置为 ONOFF(或分别设置为 1 或 0)。默认值为 OFF

  • rpl_semi_sync_source_timeout

    命令行格式 --rpl-semi-sync-source-timeout=#
    引入版本 8.0.26
    系统变量 rpl_semi_sync_source_timeout
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 10000
    最小值 0
    最大值 4294967295
    单位 毫秒

    rpl_semi_sync_source_timeout 在安装了rpl_semi_sync_sourcesemisync_source.so库)插件的复制品上设置半同步复制时可用。如果安装了rpl_semi_sync_master插件(semisync_master.so库),则可用rpl_semi_sync_master_timeout

    rpl_semi_sync_source_timeout 控制源在提交等待来自复制品的确认之前等待的时间,超时后将回滚到异步复制。该值以毫秒为单位指定,默认值为 10000(10 秒)。

  • rpl_semi_sync_source_trace_level

    命令行格式 --rpl-semi-sync-source-trace-level=#
    引入版本 8.0.26
    系统变量 rpl_semi_sync_source_trace_level
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 32
    最小值 0
    最大值 4294967295

    rpl_semi_sync_source_trace_level 在安装了rpl_semi_sync_sourcesemisync_source.so库)插件的复制品上设置半同步复制时可用。如果安装了rpl_semi_sync_master插件(semisync_master.so库),则可用rpl_semi_sync_master_trace_level

    rpl_semi_sync_source_trace_level 指定源服务器上半同步复制的调试跟踪级别。定义了四个级别:

    • 1 = 一般级别(例如,时间函数失败)

    • 16 = 详细级别(更详细的信息)

    • 32 = 网络等待级别(有关网络等待的更多信息)

    • 64 = 函数级别(有关函数进入和退出的信息)

  • rpl_semi_sync_source_wait_for_replica_count

    命令行格式 --rpl-semi-sync-source-wait-for-replica-count=#
    引入版本 8.0.26
    系统变量 rpl_semi_sync_source_wait_for_replica_count
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 1
    最小值 1
    最大值 65535

    当在副本上安装了 rpl_semi_sync_source (semisync_source.so 库) 插件以设置半同步复制时,rpl_semi_sync_source_wait_for_replica_count 就可用。如果安装了 rpl_semi_sync_master 插件 (semisync_master.so 库),则可以使用 rpl_semi_sync_master_wait_for_slave_count

    rpl_semi_sync_source_wait_for_replica_count 指定源在继续之前必须收到每个事务的副本确认数。默认情况下,rpl_semi_sync_source_wait_for_replica_count1,意味着在收到单个副本确认后,半同步复制会继续进行。对于此变量的小值,性能最佳。

    例如,如果 rpl_semi_sync_source_wait_for_replica_count2,那么在半同步复制的超时期间内,必须有 2 个副本确认接收事务,才能继续进行半同步复制。如果在超时期间内有更少的副本确认接收事务,则源将恢复为正常复制。

    注意

    这种行为还取决于 rpl_semi_sync_source_wait_no_replica

  • rpl_semi_sync_source_wait_no_replica

    命令行格式 --rpl-semi-sync-source-wait-no-replica[={OFF&#124;ON}]
    引入版本 8.0.26
    系统变量 rpl_semi_sync_source_wait_no_replica
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 ON

    当在复制品上安装了 rpl_semi_sync_sourcesemisync_source.so 库)插件以设置半同步复制时,可以使用 rpl_semi_sync_source_wait_no_replica。如果安装了 rpl_semi_sync_master 插件(semisync_master.so 库),则可以使用 rpl_semi_sync_source_wait_no_replica 控制源端是否等待由 rpl_semi_sync_source_timeout 配置的超时期限到期,即使在超时期间复制品数量少于 rpl_semi_sync_source_wait_for_replica_count 配置的数量。

    rpl_semi_sync_source_wait_no_replica 的值为 ON(默认值)时,允许在超时期间复制品数量少于 rpl_semi_sync_source_wait_for_replica_count。只要足够多的复制品在超时期限到期前确认事务,半同步复制就会继续。

    rpl_semi_sync_source_wait_no_replica 的值为 OFF 时,如果在由 rpl_semi_sync_source_timeout 配置的超时期间内任何时候复制品数量少于 rpl_semi_sync_source_wait_for_replica_count 配置的数量,源端将恢复为正常复制。

  • rpl_semi_sync_source_wait_point

    命令行格式 --rpl-semi-sync-source-wait-point=value
    引入版本 8.0.26
    系统变量 rpl_semi_sync_source_wait_point
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 枚举
    默认数值 AFTER_SYNC
    有效数值 AFTER_SYNC``AFTER_COMMIT

    当在复制品上安装了 rpl_semi_sync_sourcesemisync_source.so 库)插件以设置半同步复制时,可以使用 rpl_semi_sync_source_wait_point。如果安装了 rpl_semi_sync_master 插件(semisync_master.so 库),则可以使用 rpl_semi_sync_master_wait_point

    rpl_semi_sync_source_wait_point 控制半同步复制源服务器在返回提交事务的客户端状态之前等待副本确认事务接收的点。允许这些值:

    • AFTER_SYNC(默认):源将每个事务写入其二进制日志和副本,并将二进制日志同步到磁盘。源在同步后等待副本确认事务接收。在收到确认后,源将事务提交到存储引擎并向客户端返回结果,然后客户端可以继续。

    • AFTER_COMMIT:源将每个事务写入其二进制日志和副本,同步二进制日志,并提交事务到存储引擎。源在提交后等待副本确认事务接收。在收到确认后,源向客户端返回结果,然后客户端可以继续。

    这些设置的复制特性有以下不同:

    • 使用AFTER_SYNC,所有客户端同时看到已提交的事务:在副本确认并在源上提交到存储引擎之后。因此,所有客户端在源上看到相同的数据。

      在源故障的情况下,所有在源上提交的事务已经被复制到副本(保存在其中继日志中)。源服务器意外退出并故障转移到副本是无损失的,因为副本是最新的。但请注意,在这种情况下源不能重新启动,必须被丢弃,因为其二进制日志可能包含未提交的事务,在二进制日志恢复后会与副本在外部化时发生冲突。

    • 使用AFTER_COMMIT,发出事务的客户端只有在服务器提交到存储引擎并接收副本确认后才会收到返回状态。在提交后和副本确认前,其他客户端可以在提交客户端之前看到已提交的事务。

      如果副本未处理事务导致出现问题,那么在源服务器意外退出并故障转移到副本的情况下,这些客户端可能会看到相对于在源上看到的数据有所丢失。

原文:dev.mysql.com/doc/refman/8.0/en/replication-options-replica.html

19.1.6.3 副本服务器选项和变量

本节介绍了适用于副本服务器的服务器选项和系统变量,包括以下内容:

  • 副本服务器的启动选项

  • 副本服务器上使用的系统变量

在命令行上或在选项文件中指定选项。许多选项可以在服务器运行时通过使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)进行设置。使用SET语法指定系统变量值。

服务器 ID。 在源和每个副本上,您必须设置server_id系统变量以建立范围从 1 到 2³² − 1 的唯一复制 ID。 “唯一”意味着每个 ID 必须与复制拓扑中任何其他源或副本正在使用的任何其他 ID 不同。示例my.cnf文件:

[mysqld]
server-id=3
副本服务器的启动选项

本节介绍了控制副本服务器启动选项的内容。其中许多选项可以在服务器运行时通过使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)进行设置。其他选项,如--replicate-*选项,只能在副本服务器启动时设置。有关复制相关的系统变量将在本节后面讨论。

  • --master-info-file=*file_name*

    命令行格式 --master-info-file=file_name
    已弃用 8.0.18
    类型 文件名
    默认值 master.info

    此选项的使用现已不推荐。如果设置了master_info_repository=FILE,则用于设置复制品连接元数据存储库的文件名。--master-info-filemaster_info_repository系统变量的使用已不推荐,因为使用文件作为连接元数据存储库已被崩溃安全表取代。有关连接元数据存储库的信息,请参阅 Section 19.2.4.2, “Replication Metadata Repositories”。

  • --master-retry-count=*count*

    命令行格式 --master-retry-count=#
    已弃用
    类型 整数
    默认值 86400
    最小值 0
    最大值(64 位平台) 18446744073709551615
    最大值(32 位平台) 4294967295

    复制品在放弃之前尝试重新连接到源的次数。默认值为 86400 次。值为 0 表示“无限”,复制品会永远尝试连接。当复制品在未从源接收数据或心跳信号的情况下达到连接超时(由replica_net_timeoutslave_net_timeout系统变量指定)时,会触发重新连接尝试。重新连接尝试的间隔由CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的SOURCE_CONNECT_RETRY | MASTER_CONNECT_RETRY选项设置(默认为每 60 秒一次)。

    此选项已弃用;预计将在未来的 MySQL 版本中删除。请改用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的SOURCE_RETRY_COUNT | MASTER_RETRY_COUNT选项。

  • --max-relay-log-size=*size*

    命令行格式 --max-relay-log-size=#
    系统变量 max_relay_log_size
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 1073741824
    单位 字节
    块大小 4096

    服务器自动轮换中继日志文件的大小。如果此值非零,则当中继日志大小超过此值时,中继日志会自动轮换。如果此值为零(默认值),则中继日志轮换发生的大小由max_binlog_size的值确定。更多信息,请参阅 Section 19.2.4.1, “The Relay Log”。

  • --relay-log-purge={0|1}

    命令行格式 --relay-log-purge[={OFF&#124;ON}]
    系统变量 relay_log_purge
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 ON

    禁用或启用中继日志在不再需要时自动清除。默认值为 1(启用)。这是一个可以通过SET GLOBAL relay_log_purge = *N*动态更改的全局变量。在启用--relay-log-recovery选项时禁用中继日志清除会存在数据一致性风险,因此不具有崩溃安全性。

  • --relay-log-space-limit=*size*

    命令行格式 --relay-log-space-limit=#
    系统变量 relay_log_space_limit
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 18446744073709551615
    单位 字节

    此选项将在副本上的所有中继日志的总大小上设置一个上限,以字节为单位。值为 0 表示“无限制”。这对于具有有限磁盘空间的副本服务器主机非常有用。当达到限制时,I/O(接收器)线程停止从源服务器读取二进制日志事件,直到 SQL 线程赶上并删除一些未使用的中继日志。请注意,此限制并非绝对:在某些情况下,SQL(应用程序)线程需要更多事件才能删除中继日志。在这种情况下,接收器线程超过限制,直到应用程序线程能够删除一些中继日志,因为不这样做会导致死锁。不应将--relay-log-space-limit设置为小于--max-relay-log-size的两倍(或--max-binlog-size如果--max-relay-log-size为 0)。在这种情况下,接收器线程可能会等待空闲空间,因为--relay-log-space-limit已超过,但应用程序线程没有中继日志可清除,无法满足接收器线程。这会迫使接收器线程暂时忽略--relay-log-space-limit

  • --replicate-do-db=*db_name*

    命令行格式 --replicate-do-db=name
    类型 字符串

    使用数据库名称创建一个复制过滤器。也可以使用CHANGE REPLICATION FILTER REPLICATE_DO_DB来创建这样的过滤器。

    此选项支持通道特定的复制过滤器,使多源副本可以为不同来源使用特定的过滤器。要在名为channel_1的通道上配置特定于通道的复制过滤器,请使用--replicate-do-db:*channel_1*:*db_name*。在这种情况下,第一个冒号被解释为分隔符,后续冒号为字面冒号。有关更多信息,请参见第 19.2.5.4 节,“基于通道的复制过滤器”。

    注意

    全局复制过滤器不能用于配置为组复制的 MySQL 服务器实例,因为在某些服务器上过滤事务会使组无法达成一致状态。通道特定的复制过滤器可以用于与组复制无直接关系的复制通道,例如,其中一个组成员同时充当到组外源的副本。它们不能用于 group_replication_appliergroup_replication_recovery 通道。

    这个复制过滤器的精确效果取决于是使用基于语句还是基于行的复制。

    基于语句的复制。 告诉复制 SQL 线程将复制限制在默认数据库(即由 USE 选择的数据库)为 db_name 的语句上。要指定多个数据库,请多次使用此选项,每个数据库使用一次;但是,这样做 不会 复制跨数据库语句,例如 UPDATE *some_db.some_table* SET foo='bar',而选择了不同的数据库(或没有选择数据库)。

    警告

    要指定多个数据库,必须 使用此选项的多个实例。因为数据库名称可以包含逗号,如果提供逗号分隔的列表,则该列表被视为单个数据库的名称。

    使用基于语句的复制时不像您期望的那样工作的示例:如果副本是使用 --replicate-do-db=sales 启动的,并且您在源上发出以下语句,则 UPDATE 语句 不会 被复制:

    USE prices;
    UPDATE sales.january SET amount=amount+1000;
    

    这种“仅检查默认数据库”行为的主要原因是,仅从语句本身很难知道是否应该复制它(例如,如果您正在使用多表 DELETE 语句或跨多个数据库操作的多表 UPDATE 语句)。如果没有必要,仅检查默认数据库而不是所有数据库会更快。

    基于行的复制。 告诉复制 SQL 线程将复制限制在数据库 db_name 上。只有属于 db_name 的表会被更改;当前数据库对此没有影响。假设副本是使用 --replicate-do-db=sales 启动的,并且基于行的复制生效,然后在源上运行以下语句:

    USE prices;
    UPDATE sales.february SET amount=amount+100;
    

    副本上的sales数据库中的february表根据UPDATE语句进行更改;无论是否发出了USE语句都会发生这种情况。但是,在源上发出以下语句时,当使用行复制和--replicate-do-db=sales时,副本上没有影响:

    USE prices;
    UPDATE prices.march SET amount=amount-25;
    

    即使语句USE prices被更改为USE salesUPDATE语句的效果仍不会被复制。

    另一个在语句复制和行复制中处理--replicate-do-db的重要区别涉及到涉及多个数据库的语句。假设副本使用--replicate-do-db=db1启动,并且在源上执行以下语句:

    USE db1;
    UPDATE db1.table1, db2.table2 SET db1.table1.col1 = 10, db2.table2.col2 = 20;
    

    如果您使用语句复制,那么副本上的两个表都会被更新。但是,当使用行复制时,副本上只有table1受到影响;因为table2位于不同的数据库中,所以副本上的table2不会被UPDATE更改。现在假设,而不是USE db1语句,使用了USE db4语句:

    USE db4;
    UPDATE db1.table1, db2.table2 SET db1.table1.col1 = 10, db2.table2.col2 = 20;
    

    在这种情况下,当使用语句复制时,UPDATE语句对副本没有影响。但是,如果使用行复制,则UPDATE会更改副本上的table1,但不会更改table2—换句话说,只有由--replicate-do-db命名的数据库中的表会被更改,默认数据库的选择对此行为没有影响。

    如果需要跨数据库更新生效,请改用--replicate-wild-do-table=*db_name*.%。参见第 19.2.5 节,“服务器如何评估复制过滤规则”。

    注意

    此选项对复制的影响与--binlog-do-db对二进制日志记录的影响方式相同,并且复制格式对--replicate-do-db对复制行为的影响与日志格式对--binlog-do-db行为的影响相同。

    此选项对BEGINCOMMITROLLBACK语句无效。

  • --replicate-ignore-db=*db_name*

    命令行格式 --replicate-ignore-db=name
    类型 字符串

    使用数据库名称创建一个复制过滤器。也可以使用CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB来创建这样的过滤器。

    此选项支持通道特定的复制过滤器,使多源复制副本可以为不同源使用特定过滤器。要在名为channel_1的通道上配置通道特定的复制过滤器,请使用--replicate-ignore-db:*channel_1*:*db_name*。在这种情况下,第一个冒号被解释为分隔符,后续冒号为字面冒号。有关更多信息,请参见 Section 19.2.5.4, “Replication Channel Based Filters”。

    注意

    全局复制过滤器不能在配置为组复制的 MySQL 服务器实例上使用,因为在某些服务器上过滤事务会导致组无法达成一致状态。通道特定的复制过滤器可以用于与组复制无直接关系的复制通道,例如,其中一个组成员同时充当了组外源的副本。它们不能用于group_replication_appliergroup_replication_recovery通道。

    要忽略多个数据库,请多次使用此选项,每个数据库一次。因为数据库名称可以包含逗号,如果提供逗号分隔的列表,则将其视为单个数据库的名称。

    --replicate-do-db一样,此过滤的精确效果取决于是否使用基于语句或基于行的复制,并在接下来的几段中描述。

    基于语句的复制。 告诉复制 SQL 线程不要复制默认数据库(即由USE选择的数据库)为db_name的任何语句。

    基于行的复制。 告诉复制 SQL 线程不要更新数据库db_name中的任何表。默认数据库不受影响。

    在使用基于语句的复制时,以下示例不会按您期望的方式工作。假设副本是使用--replicate-ignore-db=sales启动的,并且您在源上发出以下语句:

    USE prices;
    UPDATE sales.january SET amount=amount+1000;
    

    在这种情况下,UPDATE语句会被复制,因为--replicate-ignore-db仅适用于默认数据库(由USE语句确定)。由于sales数据库在语句中被明确指定,因此该语句未被过滤。但是,在使用基于行的复制时,UPDATE语句的效果不会传播到副本,副本中的sales.january表的副本保持不变;在这种情况下,--replicate-ignore-db=sales导致源数据库中sales数据库中的所有表的更改都被副本忽略。

    如果您正在使用跨数据库更新并且不希望这些更新被复制,请不要使用此选项。请参阅 Section 19.2.5, “How Servers Evaluate Replication Filtering Rules”。

    如果需要跨数据库更新正常工作,请改用--replicate-wild-ignore-table=*db_name*.%。请参阅 Section 19.2.5, “How Servers Evaluate Replication Filtering Rules”。

    注意

    此选项对复制的影响方式与--binlog-ignore-db对二进制日志的影响方式相同,并且复制格式对--replicate-ignore-db对复制行为的影响与日志格式对--binlog-ignore-db行为的影响相同。

    此选项对BEGINCOMMITROLLBACK语句没有影响。

  • --replicate-do-table=*db_name.tbl_name*

    命令行格式 --replicate-do-table=name
    类型 字符串

    通过告诉复制 SQL 线程限制复制到给定表来创建复制过滤器。要指定多个表,多次使用此选项,每次为一个表。与--replicate-do-db不同,这适用于跨数据库更新和默认数据库更新。参见第 19.2.5 节,“服务器如何评估复制过滤规则”。您还可以通过发出CHANGE REPLICATION FILTER REPLICATE_DO_TABLE语句来创建这样的过滤器。

    此选项支持通道特定的复制过滤器,使多源复制可以为不同源使用特定过滤器。要在名为channel_1的通道上配置通道特定的复制过滤器,请使用--replicate-do-table:*channel_1*:*db_name.tbl_name*。在这种情况下,第一个冒号被解释为分隔符,后续冒号为字面冒号。有关更多信息,请参见第 19.2.5.4 节,“基于复制通道的过滤器”。

    注意

    全局复制过滤器不能用于配置为组复制的 MySQL 服务器实例,因为在某些服务器上过滤事务会导致组无法达成一致状态。通道特定的复制过滤器可以用于与组复制无直接关系的复制通道,例如,其中一个组成员同时充当一个在组外的源的复制。它们不能用于group_replication_appliergroup_replication_recovery通道。

    此选项仅影响适用于表的语句。它不影响仅适用于其他数据库对象(如存储过程)的语句。要过滤操作存储过程的语句,请使用一个或多个--replicate-*-db选项。

  • --replicate-ignore-table=*db_name.tbl_name*

    命令行格式 --replicate-ignore-table=name
    类型 字符串

    通过告诉复制 SQL 线程不复制更新指定表的任何语句来创建一个复制过滤器,即使同一语句可能更新其他表。要忽略多个表,请多次使用此选项,每次针对一个表。这适用于跨数据库更新,与--replicate-ignore-db相反。请参见第 19.2.5 节,“服务器如何评估复制过滤规则”。您还可以通过发出CHANGE REPLICATION FILTER REPLICATE_IGNORE_TABLE语句来创建这样的过滤器。

    此选项支持通道特定的复制过滤器,使得多源复制可以为不同源使用特定的过滤器。要在名为channel_1的通道上配置通道特定的复制过滤器,请使用--replicate-ignore-table:*channel_1*:*db_name.tbl_name*。在这种情况下,第一个冒号被解释为分隔符,后续的冒号是字面冒号。有关更多信息,请参见第 19.2.5.4 节,“基于通道的复制过滤器”。

    注意

    全局复制过滤器不能用于配置为组复制的 MySQL 服务器实例,因为在某些服务器上过滤事务会导致组无法达成一致状态。通道特定的复制过滤器可以用于与组复制无直接关系的复制通道,例如,其中一个组成员同时充当组外源的副本。它们不能用于group_replication_appliergroup_replication_recovery通道。

    此选项仅影响适用于表的语句。它不影响仅适用于其他数据库对象的语句,如存储过程。要过滤操作存储过程的语句,请使用一个或多个--replicate-*-db选项。

  • --replicate-rewrite-db=*from_name*->*to_name*

    命令行格式 --replicate-rewrite-db=old_name->new_name
    类型 字符串

    告诉副本创建一个复制过滤器,如果源上的指定数据库是from_name,则将其转换为to_name。只有涉及表的语句会受到影响,不包括CREATE DATABASEDROP DATABASEALTER DATABASE等语句。

    要指定多个重写,请多次使用此选项。服务器将使用第一个匹配from_name值的重写。数据库名称转换是在测试--replicate-*规则之前完成的。您还可以通过发出CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB语句来创建这样的过滤器。

    如果您在命令行上使用--replicate-rewrite-db选项,并且>字符对您的命令解释器很重要,请引用选项值。例如:

    $> mysqld --replicate-rewrite-db="*olddb*->*newdb*"
    

    --replicate-rewrite-db选项的效果取决于查询使用的基于语句还是基于行的二进制日志格式而有所不同。对于基于语句的格式,DML 语句基于由USE语句指定的当前数据库进行转换。对于基于行的格式,DML 语句基于修改表所在的数据库进行转换。DDL 语句始终基于由USE语句指定的当前数据库进行过滤,而不考虑二进制日志格式。

    为确保重写产生预期结果,特别是与其他复制过滤选项结合使用时,请在使用--replicate-rewrite-db选项时遵循以下建议:

    • 在源和副本上手动创建from_nameto_name数据库,名称不同。

    • 如果您使用基于语句或混合二进制日志格式,请不要使用跨数据库查询,并且不要在查询中指定数据库名称。对于 DDL 和 DML 语句,依赖USE语句来指定当前数据库,并且在查询中只使用表名。

    • 如果您仅使用基于行的二进制日志格式,对于 DDL 语句,依赖USE语句来指定当前数据库,并且在查询中只使用表名。对于 DML 语句,如果需要,可以使用完全限定的表名(db.table)。

    如果遵循这些建议,结合表级复制过滤选项(如--replicate-do-table),使用--replicate-rewrite-db选项是安全的。

    此选项支持通道特定的复制过滤器,使多源副本能够为不同源使用特定的过滤器。指定通道名称,后跟冒号,再跟过滤器规范。第一个冒号被解释为分隔符,任何后续的冒号都被解释为字面冒号。例如,要在名为channel_1的通道上配置通道特定的复制过滤器,请使用:

    $> mysqld --replicate-rewrite-db=*channel_1*:*db_name1*->*db_name2*
    

    如果使用冒号但未指定通道名称,则该选项会为默认复制通道配置复制过滤器。有关更多信息,请参见第 19.2.5.4 节,“基于复制通道的过滤器”。

    注意

    全局复制过滤器不能在配置为组复制的 MySQL 服务器实例上使用,因为在某些服务器上过滤事务会导致组无法达成一致状态。通道特定的复制过滤器可以用于与组复制无直接关系的复制通道,例如,其中一个组成员同时充当了组外源的副本。它们不能用于group_replication_appliergroup_replication_recovery通道。

  • --replicate-same-server-id

    命令行格式 --replicate-same-server-id[={OFF&#124;ON}]
    类型 布尔值
    默认值 OFF

    此选项用于副本。默认值为 0(FALSE)。将此选项设置为 1(TRUE)时,副本不会跳过具有自己服务器 ID 的事件。这个设置通常只在罕见的配置中有用。

    当在副本上启用二进制日志记录时,副本上的--replicate-same-server-id--log-slave-updates选项的组合可能导致在服务器是循环复制拓扑的一部分时出现复制中的无限循环。(在 MySQL 8.0 中,默认情况下启用二进制日志记录,并且在启用二进制日志记录时,默认情况下启用副本更新日志记录。)然而,全局事务标识符(GTID)的使用通过跳过已应用的事务的执行来防止这种情况。如果在副本上设置了gtid_mode=ON,则可以使用这些选项的组合启动服务器,但在服务器运行时不能更改为任何其他 GTID 模式。如果设置了任何其他 GTID 模式,则服务器不会以这些选项的组合启动。

    默认情况下,复制 I/O(接收器)线程不会将具有副本服务器 ID 的二进制日志事件写入中继日志(此优化有助于节省磁盘使用量)。如果要使用--replicate-same-server-id,请确保在使副本读取要复制 SQL(applier)线程执行的自己事件之前,使用此选项启动副本。

  • --replicate-wild-do-table=*db_name.tbl_name*

    命令行格式 --replicate-wild-do-table=name
    类型 字符串

    通过告知复制 SQL(applier)线程,创建一个复制过滤器,限制复制到更新表匹配指定数据库和表名模式的语句。模式可以包含%_通配符,其含义与LIKE模式匹配运算符相同。要指定多个表,需要多次使用此选项,每个表使用一次。这适用于跨数据库更新。参见 Section 19.2.5, “服务器如何评估复制过滤规则”。您也可以通过发出CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE语句来创建这样的过滤器。

    此选项支持通道特定的复制过滤器,使多源副本能够为不同源使用特定过滤器。要在名为channel_1的通道上配置通道特定的复制过滤器,请使用--replicate-wild-do-table:*channel_1*:*db_name.tbl_name*。在这种情况下,第一个冒号被解释为分隔符,后续冒号为字面冒号。有关更多信息,请参见 Section 19.2.5.4, “基于复制通道的过滤器”。

    重要

    全局复制过滤器不能在配置为组复制的 MySQL 服务器实例上使用,因为在某些服务器上过滤事务会导致组无法达成一致状态。通道特定的复制过滤器可以用于与组复制无直接关系的复制通道,例如,组成员同时充当源站外组的副本。它们不能用于group_replication_appliergroup_replication_recovery通道。

    --replicate-wild-do-table选项指定的复制过滤器适用于表、视图和触发器。它不适用于存储过程和函数,或事件。要过滤操作后者对象的语句,使用一个或多个--replicate-*-db选项。

    例如,--replicate-wild-do-table=foo%.bar%仅复制使用数据库名称以foo开头且表名以bar开头的表的更新。

    如果表名模式为%,它将匹配任何表名,并且该选项也适用于数据库级语句(CREATE DATABASEDROP DATABASEALTER DATABASE)。例如,如果您使用--replicate-wild-do-table=foo%.%,如果数据库名称与模式foo%匹配,则数据库级语句将被复制。

    重要

    表级复制过滤器仅应用于在查询中明确提及并操作的表。它们不适用于查询隐式更新的表。例如,一个GRANT语句,更新mysql.user系统表但未提及该表,不受指定mysql.%作为通配符模式的过滤器的影响。

    要在数据库或表名模式中包含字面通配符字符,请使用反斜杠进行转义。例如,要复制名为my_own%db的数据库的所有表,但不复制my1ownAABCdb数据库的表,您应该像这样转义_%字符:--replicate-wild-do-table=my\_own\%db。如果您在命令行上使用该选项,可能需要双倍反斜杠或引用选项值,具体取决于您的命令解释器。例如,在bash shell 中,您需要键入--replicate-wild-do-table=my\\_own\\%db

  • --replicate-wild-ignore-table=*db_name.tbl_name*

    命令行格式 --replicate-wild-ignore-table=name
    类型 字符串

    创建一个复制过滤器,使复制 SQL 线程不会复制任何表匹配给定通配符模式的语句。要指定要忽略的多个表,请多次使用此选项,每个表使用一次。这适用于跨数据库更新。请参阅第 19.2.5 节,“服务器如何评估复制过滤规则”。您还可以通过发出CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE语句来创建此类过滤器。

    此选项支持通道特定的复制过滤器,使多源副本可以为不同源使用特定过滤器。要在名为channel_1的通道上配置通道特定的复制过滤器,请使用--replicate-wild-ignore:*channel_1*:*db_name.tbl_name*。在这种情况下,第一个冒号被解释为分隔符,后续冒号为字面冒号。有关更多信息,请参阅第 19.2.5.4 节,“基于复制通道的过滤器”。

    重要

    全局复制过滤器不能用于配置了组复制的 MySQL 服务器实例,因为在某些服务器上过滤事务会导致组无法达成一致状态。通道特定的复制过滤器可以用于与组复制无直接关系的复制通道,例如,其中一个组成员同时充当源站外组的副本。它们不能用于group_replication_appliergroup_replication_recovery通道。

    例如,--replicate-wild-ignore-table=foo%.bar% 不会复制使用以foo开头的数据库和以bar开头的表的更新。有关匹配原理的信息,请参阅--replicate-wild-do-table选项的描述。在选项值中包含字面通配符的规则与--replicate-wild-ignore-table相同。

    重要

    表级复制过滤器仅适用于在查询中明确提及和操作的表。它们不适用于查询隐式更新的表。例如,一个GRANT语句,更新mysql.user系统表但未提及该表,不受指定mysql.%作为通配符模式的过滤器影响。

    如果需要过滤掉GRANT语句或其他管理语句,一个可能的解决方法是使用--replicate-ignore-db过滤器。该过滤器作用于当前生效的默认数据库,由USE语句确定。因此,您可以创建一个过滤器来忽略未复制的数据库的语句,然后在要忽略的任何管理语句之前立即发出USE语句以切换默认数据库到该数据库。在管理语句中,命名应用语句的实际数据库。

    例如,如果在复制服务器上配置了 --replicate-ignore-db=nonreplicated,则以下语句序列会导致 GRANT 语句被忽略,因为默认数据库 nonreplicated 生效:

    USE nonreplicated;
    GRANT SELECT, INSERT ON replicated.t1 TO 'someuser'@'somehost';
    
  • --skip-replica-start

    命令行格式 --skip-replica-start[={OFF&#124;ON}]
    引入版本 8.0.26
    系统变量 skip_replica_start
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔
    默认值 OFF

    从 MySQL 8.0.26 开始,请使用 --skip-replica-start 替代 --skip-slave-start,后者在该版本中已被弃用。在 MySQL 8.0.26 之前的版本中,请使用 --skip-slave-start

    --skip-replica-start 告诉复制服务器在启动时不要启动复制 I/O(接收器)和 SQL(应用程序)线程。要稍后启动线程,请使用 START REPLICA 语句。

    您可以使用 skip_replica_start 系统变量代替命令行选项,以允许通过 MySQL 服务器的权限结构访问此功能,从而数据库管理员无需任何操作系统的特权访问。

  • --skip-slave-start

    命令行格式 --skip-slave-start[={OFF&#124;ON}]
    已弃用 8.0.26
    系统变量 skip_slave_start
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔
    默认值 OFF

    从 MySQL 8.0.26 开始,--skip-slave-start 已被弃用,应改用别名 --skip-replica-start。在 MySQL 8.0.26 之前的版本中,请使用 --skip-slave-start

    告诉复制服务器在启动时不要启动复制 I/O(接收器)和 SQL(应用程序)线程。要稍后启动线程,请使用 START REPLICA 语句。

    从 MySQL 8.0.24 开始,您可以使用skip_slave_start系统变量来代替命令行选项,以允许使用 MySQL 服务器的权限结构访问此功能,这样数据库管理员就不需要对操作系统拥有任何特权访问。

  • --slave-skip-errors=[*err_code1*,*err_code2*,...|all|ddl_exist_errors]

    命令行格式 --slave-skip-errors=name
    已弃用 8.0.26
    系统变量 slave_skip_errors
    范围 全局
    动态
    SET_VAR提示适用
    类型 字符串
    默认值 OFF
    有效值 OFF``[错误代码列表]``all``ddl_exist_errors

    通常,当副本发生错误时,复制会停止,这为您提供了手动解决数据不一致性的机会。此选项使复制 SQL 线程在语句返回选项值中列出的任何错误时继续复制。

    除非您完全理解为什么会出现错误,否则不要使用此选项。如果您的复制设置和客户端程序中没有错误,MySQL 本身也没有错误,那么应该永远不会发生导致复制停止的错误。滥用此选项会导致副本与源头彻底失去同步,而您却不知道为什么会发生这种情况。

    对于错误代码,您应该使用副本错误日志和SHOW REPLICA STATUS输出中提供的错误消息中的数字。附录 B,错误消息和常见问题列出了服务器错误代码。

    简写值ddl_exist_errors等同于错误代码列表1007,1008,1050,1051,1054,1060,1061,1068,1094,1146

    您也可以(但不应该)使用非常不推荐的值all,使副本忽略所有错误消息并继续进行,无论发生什么情况。不用说,如果您使用all,则关于数据完整性就没有任何保证。如果副本的数据与源头的数据差距很大,请不要在这种情况下抱怨(或提交错误报告)。您已经被警告

    在复制 NDB 集群之间时,此选项的工作方式与复制内部NDB机制检查时期序列号不同;通常,一旦NDB检测到缺失或其他序列不正确的时期号,它立即停止副本应用程序线程。从 NDB 8.0.28 开始,您可以通过同时指定--ndb-applier-allow-skip-epoch--slave-skip-errors来覆盖此行为;这样做会导致NDB忽略跳过的时期事务。

    示例:

    --slave-skip-errors=1062,1053
    --slave-skip-errors=all
    --slave-skip-errors=ddl_exist_errors
    
  • --slave-sql-verify-checksum={0|1}

    命令行格式 --slave-sql-verify-checksum[={OFF&#124;ON}]
    类型 布尔值
    默认值 ON

    启用此选项时,副本会检查从中继日志中读取的校验和。如果不匹配,则副本会出现错误。

以下选项仅在 MySQL 测试套件内部用于复制测试和调试。不适用于生产环境。

  • --abort-slave-event-count

    命令行格式 --abort-slave-event-count=#
    已弃用 8.0.29
    类型 整数
    默认值 0
    最小值 0

    当将此选项设置为除 0(默认值)之外的某个正整数value时,它会影响复制行为如下:在复制 SQL 线程启动后,允许执行value个日志事件;之后,复制 SQL 线程不再接收任何事件,就好像源端的网络连接被切断一样。复制 SQL 线程继续运行,并且SHOW REPLICA STATUS的输出在Replica_IO_RunningReplica_SQL_Running列中都显示Yes,但不再从中继日志中读取更多事件。

    此选项仅在 MySQL 测试套件内部用于复制测试和调试。不适用于生产环境。从 MySQL 8.0.29 开始,已弃用,并可能在将来的 MySQL 版本中移除。

  • --disconnect-slave-event-count

    命令行格式 --disconnect-slave-event-count=#
    已弃用 8.0.29
    类型 整数
    默认值 0

    此选项仅在 MySQL 测试套件内部用于复制测试和调试。不适用于生产环境。从 MySQL 8.0.29 开始,已弃用,并可能在将来的 MySQL 版本中移除。

用于副本服务器的系统变量

以下列表描述了用于控制复制服务器的系统变量。它们可以在服务器启动时设置,其中一些可以在运行时使用 SET 进行更改。用于复制的服务器选项在本节的前面列出。

  • init_replica

    命令行格式 --init-replica=name
    引入 8.0.26
    系统变量 init_replica
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    从 MySQL 8.0.26 开始,请使用 init_replica 代替已在该版本中弃用的 init_slave。在 MySQL 8.0.26 之前的版本中,请使用 init_slave

    init_replica 类似于 init_connect,但是是每次复制 SQL 线程启动时由复制服务器执行的字符串。该字符串的格式与 init_connect 变量相同。此变量的设置将对后续的 START REPLICA 生效。

    注意

    复制 SQL 线程在执行 init_replica 之前向客户端发送确认。因此,在 START REPLICA 返回之前,不能保证已执行 init_replica。有关更多信息,请参见 Section 15.4.2.6, “START REPLICA 语句”。

  • init_slave

    命令行格式 --init-slave=name
    已弃用 8.0.26
    系统变量 init_slave
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    从 MySQL 8.0.26 开始,init_slave 已被弃用,应改用别名 init_replica。在 MySQL 8.0.26 之前的版本中,请使用 init_slave

    init_slave 类似于 init_connect,但是是一个字符串,每次复制 SQL 线程启动时由副本服务器执行。字符串的格式与 init_connect 变量相同。此变量的设置将对后续的 START REPLICA 语句生效。

    注意

    复制 SQL 线程在执行 init_slave 之前向客户端发送确认。因此,在 START REPLICA 返回之前,不能保证 init_slave 已执行。有关更多信息,请参见 Section 15.4.2.6, “START REPLICA Statement”。

  • log_slow_replica_statements

    命令行格式 --log-slow-replica-statements[={OFF&#124;ON}]
    引入版本 8.0.26
    系统变量 log_slow_replica_statements
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    从 MySQL 8.0.26 开始,使用 log_slow_replica_statements 替代从该版本开始弃用的 log_slow_slave_statements。在 MySQL 8.0.26 之前的版本中,请使用 log_slow_slave_statements

    当慢查询日志启用时,log_slow_replica_statements 启用记录在副本上执行时间超过 long_query_time 秒的查询。请注意,如果使用基于行的复制(binlog_format=ROW),则 log_slow_replica_statements 不起作用。仅当以语句格式在二进制日志中记录查询时,即设置 binlog_format=STATEMENT 或设置 binlog_format=MIXED 且语句以语句格式记录时,才将查询添加到副本的慢查询日志中。即使启用了 log_slow_replica_statements,当以行格式记录慢查询时,当设置 binlog_format=MIXED 时,或者当设置 binlog_format=ROW 时记录时,这些慢查询不会添加到副本的慢查询日志中。

    设置 log_slow_replica_statements 没有立即效果。该变量的状态适用于所有后续的 START REPLICA 语句。还要注意,全局设置的 long_query_time 适用于 SQL 线程的生命周期。如果更改了该设置,必须停止并重新启动复制 SQL 线程以实施更改(例如,通过使用带有 SQL_THREAD 选项的 STOP REPLICASTART REPLICA 语句)。

  • log_slow_slave_statements

    命令行格式 --log-slow-slave-statements[={OFF&#124;ON}]
    已弃用 8.0.26
    系统变量 log_slow_slave_statements
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    从 MySQL 8.0.26 开始,log_slow_slave_statements 已被弃用,应改用别名 log_slow_replica_statements。在 MySQL 8.0.26 之前的版本中,请使用 log_slow_slave_statements

    当慢查询日志被启用时,log_slow_slave_statements 会记录在副本上执行时间超过long_query_time秒的查询。请注意,如果使用基于行的复制(binlog_format=ROW),log_slow_slave_statements 不会生效。只有当查询以语句格式在二进制日志中记录时,即当设置binlog_format=STATEMENT,或者当设置binlog_format=MIXED并且语句以语句格式记录时,查询才会被添加到副本的慢查询日志中。即使启用了log_slow_slave_statements,当以行格式记录慢查询时,当设置binlog_format=MIXED时,或者当设置binlog_format=ROW时记录时,这些慢查询也不会被添加到副本的慢查询日志中。

    设置log_slow_slave_statements 没有立即生效。该变量的状态适用于所有后续的START REPLICA语句。还要注意,全局设置的long_query_time适用于 SQL 线程的生命周期。如果更改了该设置,必须停止并重新启动复制 SQL 线程以在那里实施更改(例如,通过使用带有SQL_THREAD选项的STOP REPLICASTART REPLICA语句)。

  • master_info_repository

    命令行格式 --master-info-repository={FILE&#124;TABLE}
    已弃用 8.0.23
    系统变量 master_info_repository
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 TABLE
    有效值 FILE``TABLE

    现在已弃用此系统变量的使用。设置TABLE是默认值,并且在配置多个复制通道时是必需的。曾经弃用的替代设置FILE

    默认设置下,副本将关于源的元数据(包括状态和连接信息)记录到 mysql 系统数据库中的 mysql.slave_master_info 表中的 InnoDB 表中。有关连接元数据存储库的更多信息,请参见 第 19.2.4 节,“中继日志和复制元数据存储库”。

    FILE 设置将副本的连接元数据存储库写入一个文件,默认情况下命名为 master.info。可以使用 --master-info-file 选项更改名称。

  • max_relay_log_size

    命令行格式 --max-relay-log-size=#
    系统变量 max_relay_log_size
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 1073741824
    单位 字节
    块大小 4096

    如果副本对其中继日志的写入导致当前日志文件大小超过此变量的值,则副本会旋转中继日志(关闭当前文件并打开下一个文件)。如果 max_relay_log_size 为 0,则服务器对二进制日志和中继日志均使用 max_binlog_size。如果 max_relay_log_size 大于 0,则限制中继日志的大小,这使您可以为两个日志设置不同的大小。必须将 max_relay_log_size 设置为介于 4096 字节和 1GB(包括)之间,或为 0。默认值为 0。请参阅 第 19.2.3 节,“复制线程”。

  • relay_log

    命令行格式 --relay-log=file_name
    系统变量 relay_log
    范围 全局
    动态
    SET_VAR 提示适用
    类型 文件名

    中继日志文件的基本名称。对于默认复制通道,中继日志的默认基本名称为 *host_name*-relay-bin。对于非默认复制通道,中继日志的默认基本名称为 *host_name*-relay-bin-*channel*,其中 channel 是此中继日志中记录的复制通道的名称。

    服务器将文件写入数据目录,除非使用具有前导绝对路径名的基本名称来指定不同目录。服务器通过向基本名称添加数字后缀按顺序创建中继日志文件。

    在复制服务器上,中继日志和中继日志索引不能与由--log-bin--log-bin-index选项指定的二进制日志和二进制日志索引具有相同的名称。如果二��制日志和中继日志文件基本名称相同,服务器会发出错误消息并且不会启动。

    由于 MySQL 解析服务器选项的方式,如果您在服务器启动时指定了这个变量,您必须提供一个值;只有在实际未指定该选项时才使用默认基本名称。如果在服务器启动时指定relay_log系统变量而没有指定值,可能会导致意外行为;这取决于使用的其他选项、指定它们的顺序以及它们是在命令行中指定还是在选项文件中指定。有关 MySQL 如何处理服务器选项的更多信息,请参见第 6.2.2 节,“指定程序选项”。

    如果您指定了这个变量,那么指定的值也将用作中继日志索引文件的基本名称。您可以通过使用relay_log_index系统变量指定不同的中继日志索引文件基本名称来覆盖此行为。

    当服务器从索引文件中读取条目时,它会检查条目是否包含相对路径。如果包含,路径的相对部分将被使用relay_log系统变量设置的绝对路径替换。绝对路径保持不变;在这种情况下,必须手动编辑索引以启用新路径或路径的使用。

    您可能会发现relay_log系统变量在执行以下任务时很有用:

    • 创建与主机名无关的中继日志的名称。

    • 如果您需要将中继日志放在数据目录之外的某个区域,因为您的中继日志往往非常大,并且您不想减少max_relay_log_size

    • 通过在磁盘之间使用负载平衡来提高速度。

    您可以从relay_log_basename系统变量中获取中继日志文件名(和路径)。

  • relay_log_basename

    系统变量 relay_log_basename
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 文件名
    默认值 datadir + '/' + hostname + '-relay-bin'

    保存中继日志文件的基本名称和完整路径。最大变量长度为 256。此变量由服务器设置,只读。

  • relay_log_index

    命令行格式 --relay-log-index=file_name
    系统变量 relay_log_index
    范围 全局
    动态
    SET_VAR 提示适用
    类型 文件名
    默认值 *host_name*-relay-bin.index

    中继日志索引文件的名称。最大变量长度为 256。如果未指定此变量,但指定了relay_log系统变量,则其值将用作中继日志索引文件的默认基本名称。如果relay_log也未指定,则对于默认复制通道,默认名称为*host_name*-relay-bin.index,使用主机机器的名称。对于非默认复制通道,默认名称为*host_name*-relay-bin-*channel*.index,其中channel是在此中继日志索引中记录的复制通道的名称。

    中继日志文件的默认位置是数据目录,或者使用relay_log系统变量指定的任何其他位置。您可以使用relay_log_index系统变量指定替代位置,通过在基本名称前添加一个绝对路径名来指定不同的目录。

    复制服务器上的中继日志和中继日志索引不能与二进制日志和二进制日志索引具有相同的名称,其名称由--log-bin--log-bin-index选项指定。如果二进制日志和中继日志文件的基本名称相同,服务器会发出错误消息并且不会启动。

    由于 MySQL 解析服务器选项的方式,如果在服务器启动时指定此变量,必须提供一个值;只有在实际未指定该选项时才使用默认基本名称。 如果在服务器启动时指定 relay_log_index 系统变量而没有指定值,可能会导致意外行为;此行为取决于使用的其他选项、指定它们的顺序以及它们是在命令行中指定还是在选项文件中指定。 有关 MySQL 如何处理服务器选项的更多信息,请参见 第 6.2.2 节,“指定程序选项”。

  • relay_log_info_file

    命令行格式 --relay-log-info-file=file_name
    弃用 8.0.18
    系统变量 relay_log_info_file
    范围 全局
    动态
    SET_VAR提示适用
    类型 文件名
    默认值 relay-log.info

    此系统变量的使用现已弃用。 如果设置了 relay_log_info_repository=FILE,则用于设置复制品的应用程序元数据存储库的文件名。 relay_log_info_filerelay_log_info_repository 系统变量的使用已被弃用,因为使用文件作为应用程序元数据存储库已被崩溃安全表取代。 有关应用程序元数据存储库的信息,请参见 第 19.2.4.2 节,“复制元数据存储库”。

  • relay_log_info_repository

    命令行格式 --relay-log-info-repository=value
    弃用 8.0.23
    系统变量 relay_log_info_repository
    范围 全局
    动态
    SET_VAR提示适用
    类型 字符串
    默认值 TABLE
    有效值 FILE``TABLE

    此系统变量的使用现已不推荐。TABLE 是默认设置,当配置多个复制通道时,必须使用 TABLE 设置。副本的应用程序元数据存储库也需要 TABLE 设置,以使复制对意外停止具有弹性。有关更多信息,请参见 Section 19.4.2, “Handling an Unexpected Halt of a Replica”。曾经不推荐使用替代设置 FILE

    默认设置下,副本将其应用程序元数据存储库存储为 InnoDB 表,存储在名为 mysql.slave_relay_log_infomysql 系统数据库中。有关应用程序元数据存储库的更多信息,请参见 Section 19.2.4, “Relay Log and Replication Metadata Repositories”。

    默认情况下,FILE 设置将副本的应用程序元数据存储库写入文件,默认情况下命名为 relay-log.info。可以使用 relay_log_info_file 系统变量更改名称。

  • relay_log_purge

    命令行格式 --relay-log-purge[={OFF&#124;ON}]
    系统变量 relay_log_purge
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 ON

    禁用或启用中继日志文件在不再需要时立即清除。默认值为 1(ON)。

  • relay_log_recovery

    命令行格式 --relay-log-recovery[={OFF&#124;ON}]
    系统变量 relay_log_recovery
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    如果启用此变量,它将在服务器启动后立即启用自动中继日志恢复。恢复过程将创建一个新的中继日志文件,将 SQL(应用程序)线程位置初始化为此新中继日志,并将 I/O(接收器)线程初始化为应用程序线程位置。然后继续从源读取中继日志。如果为使用 CHANGE REPLICATION SOURCE TO 选项为复制通道设置了 SOURCE_AUTO_POSITION=1,则用于启动复制的源位置可能是在连接中接收到的位置,而不是在此过程中分配的位置。

    此全局变量在运行时是只读的。可以在复制服务器启动时使用--relay-log-recovery选项设置其值,该选项应在复制品意外停止后使用,以确保不处理可能损坏的中继日志,并且必须使用以确保崩溃安全的复制品。默认值为 0(禁用)。有关在复制品上设置的组合设置,以使其对意外停止最具弹性,请参见第 19.4.2 节,“处理复制品意外停止”。

    对于多线程复制品(其中replica_parallel_workersslave_parallel_workers大于 0),在启动时设置--relay-log-recovery会自动处理已从中继日志执行的事务序列中的任何不一致和间隙。当使用基于文件位置的复制时,这些间隙可能会发生。(有关更多详细信息,请参见第 19.5.1.34 节,“复制和事务不一致性”。)中继日志恢复过程使用与START REPLICA UNTIL SQL_AFTER_MTS_GAPS语句相同的方法处理间隙。当复制品达到一致的无间隙状态时,中继日志恢复过程继续从源处获取进一步的事务,从 SQL(应用程序)线程位置开始。当使用基于 GTID 的复制时,从 MySQL 8.0.18 开始,多线程复制品首先检查MASTER_AUTO_POSITION是否设置为ON,如果是,则省略计算应跳过或不跳过的事务的步骤,因此不需要旧的中继日志进行恢复过程。

    注意

    此变量不会影响以下 Group Replication 通道:

    • group_replication_applier

    • group_replication_recovery

    任何其他在组上运行的通道都会受到影响,例如从外部来源或另一个组复制的通道。

  • relay_log_space_limit

    命令行格式 --relay-log-space-limit=#
    系统变量 relay_log_space_limit
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 18446744073709551615
    单位 字节

    用于所有中继日志的最大空间量。

  • replica_checkpoint_group

    命令行格式 --replica-checkpoint-group=#
    引入版本 8.0.26
    系统变量 replica_checkpoint_group
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 512
    最小值 32
    最大值 524280
    块大小 8

    从 MySQL 8.0.26 开始,使用replica_checkpoint_group代替slave_checkpoint_group,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用slave_checkpoint_group

    replica_checkpoint_group 设置多线程副本在调用检查点操作之前可以处理的最大事务数,如SHOW REPLICA STATUS所示。设置此变量对未启用多线程的副本没有影响。设置此变量没有立即效果。该变量的状态适用于所有后续的START REPLICA语句。

    以前,NDB Cluster 不支持多线程副本,对于此变量的设置会被静默忽略。这个限制在 MySQL 8.0.33 中被取消。

    此变量与replica_checkpoint_period系统变量结合使用,当超过任一限制时,将执行检查点并重置跟踪事务数量和自上次检查点以来经过的时间的计数器。

    此变量的最小允许值为 32,除非服务器是使用-DWITH_DEBUG构建的,在这种情况下,最小值为 1。有效值始终是 8 的倍数;您可以将其设置为不是这种倍数的值,但服务器会在存储值之前将其向下舍入到下一个较低的 8 的倍数。(例外: 调试服务器不执行此舍入。)无论服务器是如何构建的,默认值都是 512,最大允许值为 524280。

  • replica_checkpoint_period

    命令行格式 --replica-checkpoint-period=#
    引入版本 8.0.26
    系统变量 replica_checkpoint_period
    作用范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 300
    最小值 1
    最大值 4294967295
    单位 毫秒

    在 MySQL 8.0.26 及更高版本中,使用replica_checkpoint_period代替slave_checkpoint_period,后者从该版本开始被弃用;在 MySQL 8.0.26 之前,请使用slave_checkpoint_period

    replica_checkpoint_period设置了允许经过的最长时间(以毫秒为单位),在调用检查点操作以更新多线程副本状态之前。设置此变量对于未启用多线程的副本没有影响。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    以前,NDB Cluster 不支持多线程副本,对于这个变量的设置被静默忽略。这个限制在 MySQL 8.0.33 中被取消。

    此变量与replica_checkpoint_group系统变量结合使用,当超过任一限制时,将执行检查点并重置跟踪事务数量和自上次检查点以来经过的时间的计数器。

    除非服务器是使用-DWITH_DEBUG构建的,否则此变量的最小允许值为 1,此时最小值为 0。无论服务器是如何构建的,默认值为 300 毫秒,最大可能值为 4294967295 毫秒(约 49.7 天)。

  • replica_compressed_protocol

    命令行格式 --replica-compressed-protocol[={OFF&#124;ON}]
    引入版本 8.0.26
    系统变量 replica_compressed_protocol
    作用范围 全局
    动态
    SET_VAR提示适用
    类型 布尔值
    默认值 OFF

    从 MySQL 8.0.26 开始,请使用replica_compressed_protocol代替已弃用的slave_compressed_protocol。在 MySQL 8.0.26 之前的版本中,请使用slave_compressed_protocol

    replica_compressed_protocol指定是否在源和副本都支持时使用源/副本连接协议的压缩。如果禁用此变量(默认值),则连接是未压缩的。对此变量的更改将在后续的连接尝试中生效;这包括发出START REPLICA语句后,以及由正在运行的复制 I/O(接收器)线程进行的重新连接。

    二进制日志事务压缩(自 MySQL 8.0.20 起可用),由binlog_transaction_compression系统变量激活,也可用于节省带宽。如果将二进制日志事务压缩与协议压缩结合使用,则协议压缩的作用数据减少,但仍可压缩标头以及未压缩的事件和事务有效载荷。有关二进制日志事务压缩的更多信息,请参见第 7.4.4.5 节,“二进制日志事务压缩”。

    如果启用了replica_compressed_protocol,则优先于为CHANGE REPLICATION SOURCE TO语句指定的任何SOURCE_COMPRESSION_ALGORITHMS选项。在这种情况下,如果源和副本都支持该算法,则源到副本的连接使用zlib压缩。如果禁用了replica_compressed_protocol,则应用SOURCE_COMPRESSION_ALGORITHMS的值。有关更多信息,请参见第 6.2.8 节,“连接压缩控制”。

  • replica_exec_mode

    命令行格式 --replica-exec-mode=mode
    引入版本 8.0.26
    系统变量 replica_exec_mode
    范围 全局
    动态
    SET_VAR提示适用
    类型 枚举
    默认值 幂等(NDB)严格(其他)
    有效值 严格``幂等

    从 MySQL 8.0.26 开始,使用 replica_exec_mode 替代 slave_exec_mode,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用 slave_exec_mode

    replica_exec_mode 控制复制线程在复制过程中如何解决冲突和错误。IDEMPOTENT 模式会导致重复键和未找到键的错误被抑制;STRICT 表示不会发生此类抑制。

    IDEMPOTENT 模式旨在用于多源复制、循环复制以及一些其他特殊的 NDB 集群复制场景。(详见 第 25.7.10 节,“NDB 集群复制:双向和循环复制”,以及 第 25.7.12 节,“NDB 集群复制冲突解决”,获取更多信息。)NDB 集群会忽略为 replica_exec_mode 明确设置的任何值,并始终将其视为 IDEMPOTENT

    在 MySQL Server 8.0 中,STRICT 模式是默认值。

    设置此变量会立即对所有复制通道生效,包括正在运行的通道。

    对于除了 NDB 外的存储引擎,只有在您绝对确定重复键错误和未找到键错误可以安全忽略时才应使用 IDEMPOTENT 模式。它旨在用于 NDB 集群的故障转移场景,其中使用了多源复制或循环复制,并不建议在其他情况下使用。

  • replica_load_tmpdir

    命令行格式 --replica-load-tmpdir=dir_name
    引入版本 8.0.26
    系统变量 replica_load_tmpdir
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 目录名称
    默认值 --tmpdir 的值

    从 MySQL 8.0.26 开始,使用 replica_load_tmpdir 替代 slave_load_tmpdir,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用 slave_load_tmpdir

    replica_load_tmpdir 指定了副本创建临时文件的目录名称。设置此变量会立即对所有复制通道生效,包括正在运行的通道。该变量的值默认等于tmpdir系统变量的值,或者在未指定该系统变量时适用的默认值。

    当复制 SQL 线程复制LOAD DATA语句时,它会将要加载的文件从中继日志提取到临时文件中,然后将这些文件加载到表中。如果源上加载的文件很大,副本上的临时文件也很大。因此,建议使用此选项告诉副本将临时文件放在某个具有大量可用空间的文件系统中的目录中。在这种情况下,中继日志也很大,因此您可能还想设置relay_log系统变量将中继日志放在该文件系统中。

    此选项指定的目录应位于基于磁盘的文件系统中(而非基于内存的文件系统),以便用于复制LOAD DATA语句的临时文件可以在机器重新启动时保留。该目录也不应该是在系统启动过程中被操作系统清除的目录。然而,如果临时文件已被删除,复制现在可以在重新启动后继续。

  • replica_max_allowed_packet

    命令行格式 --replica-max-allowed-packet=#
    引入版本 8.0.26
    系统变量 replica_max_allowed_packet
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 1073741824
    最小值 1024
    最大值 1073741824
    单位 字节
    块大小 1024

    从 MySQL 8.0.26 开始,请使用replica_max_allowed_packet代替从该版本开始已弃用的slave_max_allowed_packet。在 MySQL 8.0.26 之前的版本中,请使用slave_max_allowed_packet

    replica_max_allowed_packet设置了复制 SQL(应用程序)和 I/O(接收器)线程可以处理的最大数据包大小(以字节为单位)。设置此变量立即对所有复制通道生效,包括正在运行的通道。一旦添加了事件头,源端可以写入比其max_allowed_packet设置更长的二进制日志事件。replica_max_allowed_packet的设置必须大于源端的max_allowed_packet设置,以确保使用基于行的复制进行大型更新时不会导致复制失败。

    此全局变量始终具有值,该值是 1024 的正整数倍;如果将其设置为非 1024 的值,则该值将向上舍入为下一个最高的 1024 的倍数以进行存储或使用;将replica_max_allowed_packet设置为 0 会导致使用 1024。(在所有这些情况下都会发出截断警告。)默认值和最大值为 1073741824(1 GB);最小值�� 1024。

  • replica_net_timeout

    命令行格式 --replica-net-timeout=#
    引入版本 8.0.26
    系统变量 replica_net_timeout
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 60
    最小值 1
    最大值 31536000
    单位

    从 MySQL 8.0.26 开始,使用replica_net_timeout代替从该版本开始已弃用的slave_net_timeout。在 MySQL 8.0.26 之前的版本中,请使用slave_net_timeout

    replica_net_timeout指定了复制品在从源端等待更多数据或心跳信号之前的秒数,如果复制品认为连接中断,则中止读取并尝试重新连接。设置此变量不会立即生效。变量的状态适用于所有后续的START REPLICA命令。

    默认值为 60 秒(一分钟)。超时后立即进行第一次重试。重试间隔由CHANGE REPLICATION SOURCE TO���句的SOURCE_CONNECT_RETRY选项控制,重新连接尝试次数由SOURCE_RETRY_COUNT选项限制。

    心跳间隔由 CHANGE REPLICATION SOURCE TO 语句的 SOURCE_HEARTBEAT_PERIOD 选项控制,该选项防止在连接仍然良好的情况下在没有数据的情况下发生连接超时。心跳间隔默认为 replica_net_timeout 值的一半,并记录在副本的连接元数据存储库中,并显示在 replication_connection_configuration 性能模式表中。请注意,对于 replica_net_timeout 的值或默认设置的更改不会自动更改心跳间隔,无论是显式设置还是使用先前计算的默认值。如果更改连接超时时间,您还必须发出 CHANGE REPLICATION SOURCE TO 来调整心跳间隔到一个适当的值,以便在连接超时之前发生。

  • replica_parallel_type

    命令行格式 --replica-parallel-type=value
    引入版本 8.0.26
    已弃用 8.0.29
    系统变量 replica_parallel_type
    范围 全局
    动态
    SET_VAR 提示适用
    类型 枚举
    默认值(≥ 8.0.27) LOGICAL_CLOCK
    默认值(8.0.26) DATABASE
    有效值 DATABASE``LOGICAL_CLOCK

    从 MySQL 8.0.26 开始,使用 replica_parallel_type 替代从该版本开始已弃用的 slave_parallel_type。在 MySQL 8.0.26 之前的版本中,请使用 slave_parallel_type

    对于多线程副本(replica_parallel_workersslave_parallel_workers 设置为大于 0 的值的副本),replica_parallel_type 指定了在副本上决定哪些事务可以并行执行的策略。该变量对于未启用多线程的副本没有影响。可能的值包括:

    • LOGICAL_CLOCK: 事务在副本上并行应用,基于复制源写入二进制日志的时间戳。根据时间戳跟踪事务之间的依赖关系,以在可能的情况下提供额外的并行化。

    • DATABASE: 更新不同数据库的事务并行应用。只有在数据被分区到多个独立并且同时在源上更新的数据库时才适用此值。不能有跨数据库约束,因为这样的约束可能在副本上被违反。

    当启用replica_preserve_commit_orderslave_preserve_commit_order时,必须使用LOGICAL_CLOCK。在 MySQL 8.0.27 之前,DATABASE是默认值。从 MySQL 8.0.27 开始,默认情况下为副本服务器启用多线程(replica_parallel_workers=4为默认值),并且LOGICAL_CLOCK是默认值。(在 MySQL 8.0.27 及更高版本中,默认情况下还启用了replica_preserve_commit_order。)

    当复制拓扑结构使用多级副本时,LOGICAL_CLOCK可能会使每个副本距源的级别的并行化减少。为了补偿这种影响,您应该在源上以及每个中间副本上将binlog_transaction_dependency_tracking设置为WRITESETWRITESET_SESSION,以指定在可能的情况下使用写入集而不是时间戳进行并行化。

    当使用binlog_transaction_compression系统变量启用二进制日志事务压缩时,如果将replica_parallel_type设置为DATABASE,则在调度事务之前会映射受事务影响的所有数据库。使用DATABASE策略的二进制日志事务压缩可能会减少与未压缩事务相比的并行性,后者会为每个事件映射并调度。

    replica_parallel_type从 MySQL 8.0.29 开始已弃用,使用数据库分区的事务并行化也已弃用。预计在未来的版本中将删除对这些的支持,并且之后将专门使用LOGICAL_CLOCK

  • replica_parallel_workers

    命令行格式 --replica-parallel-workers=#
    引入版本 8.0.26
    系统变量 replica_parallel_workers
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值(≥ 8.0.27) 4
    默认值(8.0.26) 0
    最小值 0
    最大值 1024

    从 MySQL 8.0.26 开始,slave_parallel_workers 已不推荐使用,应改为使用 replica_parallel_workers。 (在 MySQL 8.0.26 之前,必须使用 slave_parallel_workers 来设置应用程序线程的数量。)

    replica_parallel_workers 启用副本的多线程,并设置用于并行执行复制事务的应用程序线程数。当值大于或等于 1 时,副本使用指定数量的工作线程来执行事务,还有一个协调器线程从中继日志中读取事务并将其调度给工作线程。当值为 0 时,只有一个线程按顺序读取和应用事务。如果使用多个复制通道,则此变量的值适用于每个通道使用的线程。

    在 MySQL 8.0.27 之前,此系统变量的默认值为 0,因此副本默认使用单个工作线程。从 MySQL 8.0.27 开始,默认值为 4,这意味着副本默认为多线程。

    截至 MySQL 8.0.30,将此变量设置为 0 已不推荐使用,会引发警告,并可能在将来的 MySQL 版本中删除。对于单个工作线程,请将 replica_parallel_workers 设置为 1。

    replica_preserve_commit_order(或 slave_preserve_commit_order)设置为 ON(MySQL 8.0.27 及更高版本的默认设置),副本上的事务按照在副本的中继日志中出现的顺序在副本上外部化。事务在应用程序线程之间的分配方式由 replica_parallel_type(MySQL 8.0.26 及更高版本)或 slave_parallel_type(MySQL 8.0.26 之前)确定。从 MySQL 8.0.27 开始,这些系统变量也具有适当的多线程默认值。

    要禁用并行执行,请将replica_parallel_workers设置为 1,这样副本将使用一个协调线程读取事务,一个工作线程应用事务,这意味着事务按顺序应用。当replica_parallel_workers等于 1 时,replica_parallel_typeslave_parallel_type)和replica_preserve_commit_orderslave_preserve_commit_order)系统变量不起作用,会被忽略。如果replica_parallel_workers等于 0,同时启用CHANGE REPLICATION SOURCE TO选项GTID_ONLY,副本将有一个协调线程和一个工作线程,就像replica_parallel_workers被设置为 1 一样。(GTID_ONLY在 MySQL 8.0.27 及更高版本中可用。)有一个并行工作者时,replica_preserve_commit_orderslave_preserve_commit_order)系统变量也不起作用。

    设置replica_parallel_workers没有立即效果,而是适用于所有后续的START REPLICA语句。

    多线程副本从 NDB Cluster 8.0.33 版本开始受支持。(之前,NDB会默默忽略replica_parallel_workers的任何设置。)更多信息请参见第 25.7.11 节,“使用多线程应用程序的 NDB Cluster 复制”。

    增加工作者数量可以提高并行性的潜力。通常情况下,这会提高性能,直到某个点,之后增加工作者数量会由于并发效应(如锁争用)而降低性能。理想数量取决于硬件和工作负载;很难预测,通常需要通过测试找到。没有主键的表总是会损害性能,在replica_parallel_workers > 1 的副本上可能会产生更大的负面性能影响;因此,在启用此选项之前,请确保所有表都有主键。

  • replica_pending_jobs_size_max

    命令行格式 --replica-pending-jobs-size-max=#
    引入版本 8.0.26
    系统变量 `replica_pending_jobs_size_max``
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 128M
    最小值 1024
    最大值 16EiB
    单位 字节
    块大小 1024

    从 MySQL 8.0.26 开始,使用replica_pending_jobs_size_max代替从该版本开始已弃用的slave_pending_jobs_size_max。在 MySQL 8.0.26 之前的版本中,使用slave_pending_jobs_size_max

    对于多线程复制品,此变量设置了可用于尚未应用的事件的 applier 队列的最大内存量(以字节为单位)。设置此变量对未启用多线程的复制品没有影响。设置此变量没有立即效果。变量的状态适用于所有后续的START REPLICA语句。

    此变量的最小可能值为 1024 字节;默认值为 128MB。最大可能值为 18446744073709551615(16 exbibytes)。不是 1024 字节的精确倍数的值在存储之前会被舍入为下一个较低的 1024 字节的倍数。

    此变量的值是一个软限制,可以设置为匹配正常工作负载。如果异常大的事件超过此大小,事务将被暂停,直到所有工作线程的队列为空,然后再处理。所有后续事务将被暂停,直到大事务完成。

  • replica_preserve_commit_order

    命令行格式 --replica-preserve-commit-order[={OFF&#124;ON}]
    引入 8.0.26
    系统变量 replica_preserve_commit_order
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 (≥ 8.0.27) ON
    默认值 (8.0.26) OFF

    从 MySQL 8.0.26 开始,使用replica_preserve_commit_order代替从该版本开始已弃用的slave_preserve_commit_order。在 MySQL 8.0.26 之前的版本中,使用slave_preserve_commit_order

    对于多线程复制(replica_parallel_workers 设置为大于 0 的值的复制品),设置 replica_preserve_commit_order=ON 确保事务在复制品上按照在复制品的中继日志中出现的顺序执行和提交。这可以防止在已从复制品的中继日志执行的事务序列中出现间隙,并保留与源相同的事务历史(以下列出了限制)。此变量对未启用多线程的复制品没有影响。

    在 MySQL 8.0.27 之前,此系统变量的默认值为 OFF,意味着事务可能会无序提交。从 MySQL 8.0.27 开始,默认情况下为复制品服务器启用多线程(默认为 replica_parallel_workers=4),因此 replica_preserve_commit_order=ON 是默认值,并且设置 replica_parallel_type=LOGICAL_CLOCK 也是默认值。同样从 MySQL 8.0.27 开始,如果 replica_parallel_workers 设置为 1,则 replica_preserve_commit_order 的设置将被忽略,因为在这种情况下事务的顺序已经被保留。

    二进制日志和复制品更新日志不需要在复制品上设置 replica_preserve_commit_order=ON,如果需要,可以禁用。设置 replica_preserve_commit_order=ON 要求将 replica_parallel_type 设置为 LOGICAL_CLOCK,这在 MySQL 8.0.27 之前 是默认设置。在更改 replica_preserve_commit_orderreplica_parallel_type 的值之前,必须停止复制 SQL 线程(如果使用多个复制通道,则对所有复制通道都要停止)。

    replica_preserve_commit_order=OFF被设置时,多线程复制并行应用的事务可能会无序提交。因此,检查最近执行的事务并不能保证源数据库上的所有先前事务已在复制中执行。在复制中继日志中执行的事务序列可能存在间隙的可能性。这对于使用多线程复制时的日志记录和恢复有影响。有关更多信息,请参见第 19.5.1.34 节,“复制和事务不一致性”。

    replica_preserve_commit_order=ON被设置时,执行的工作线程会等待所有先前的事务提交后再进行提交。当一个线程在等待其他工作线程提交它们的事务时,它会报告其状态为等待前一个事务提交。在这种模式下,多线程复制永远不会进入源数据库不在的状态。这支持将复制用于读取扩展。参见第 19.4.5 节,“使用复制进行扩展”。

    注意

    • replica_preserve_commit_order=ON不能防止源数据库二进制日志位置滞后,其中Exec_master_log_pos落后于已执行事务的位置。请参见第 19.5.1.34 节,“复制和事务不一致性”。

    • replica_preserve_commit_order=ON不保留如果复制使用二进制日志过滤器,如--binlog-do-db,则不保留提交顺序和事务历史。

    • replica_preserve_commit_order=ON不保留非事务性 DML 更新的顺序。这些更新可能在在中继日志中先于它们之前的事务提交,这可能导致在复制中继日志中执行的事务序列中存在间隙。

    • 如果使用基于语句的复制,并且事务性和非事务性存储引擎参与在源上回滚的非 XA 事务,可能会出现在副本上保留提交顺序的限制。通常,在源上回滚的非 XA 事务不会被复制到副本,但在这种特殊情况下,该事务可能会被复制到副本。如果发生这种情况,没有二进制日志记录的多线程副本无法处理事务回滚,因此在这种情况下,副本上的提交顺序会与中继日志中事务的顺序不同。

  • replica_sql_verify_checksum

    命令行格式 --replica-sql-verify-checksum[={OFF&#124;ON}]
    引入版本 8.0.26
    系统变量 replica_sql_verify_checksum
    范围 全局
    动态
    SET_VAR提示适用
    类型 布尔值
    默认值 ON

    从 MySQL 8.0.26 开始,请使用replica_sql_verify_checksum替代slave_sql_verify_checksum,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用slave_sql_verify_checksum

    slave_sql_verify_checksum导致复制 SQL(应用程序)线程使用从中继日志读取的校验和来验证数据。如果出现不匹配,副本将停止并显示错误。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    注意

    复制 I/O(接收器)线程在从网络接收事件时,始终尽可能读取校验和。

  • replica_transaction_retries

    命令行格式 --replica-transaction-retries=#
    引入版本 8.0.26
    系统变量 replica_transaction_retries
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 10
    最小值 0
    最大值 18446744073709551615

    从 MySQL 8.0.26 开始,使用replica_transaction_retries代替从该版本开始已弃用的slave_transaction_retries。在 MySQL 8.0.26 之前的版本中,请使用slave_transaction_retries

    replica_transaction_retries 设置了单线程或多线程副本上的复制 SQL 线程在停止之前自动重试失败事务的最大次数。设置此变量立即对所有复制通道生效,包括正在运行的通道。默认值为 10。将变量设置为 0 会禁用事务的自动重试。

    如果复制 SQL 线程由于InnoDB死锁或事务执行时间超过InnoDBinnodb_lock_wait_timeoutNDBTransactionDeadlockDetectionTimeoutTransactionInactiveTimeout而无法执行事务时,它会在停止之前自动重试replica_transaction_retries次数。非临时错误的事务不会重试。

    Performance Schema 表replication_applier_status显示了每个复制通道上发生的重试次数,在COUNT_TRANSACTIONS_RETRIES列中。Performance Schema 表replication_applier_status_by_worker显示了单线程或多线程副本上每个应用程序线程对事务重试的详细信息,并标识导致最后一个事务和当前正在进行的事务重新尝试的错误。

  • replica_type_conversions

    命令行格式 --replica-type-conversions=set
    引入版本 8.0.26
    系统变量 replica_type_conversions
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 设置
    默认值
    有效值 ALL_LOSSY``ALL_NON_LOSSY``ALL_SIGNED``ALL_UNSIGNED

    从 MySQL 8.0.26 开始,使用 replica_type_conversions 替代 slave_type_conversions,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用 slave_type_conversions

    replica_type_conversions 控制在使用基于行的复制时副本上生效的类型转换模式。其值是一个由列表中零个或多个元素组成的逗号分隔集合:ALL_LOSSYALL_NON_LOSSYALL_SIGNEDALL_UNSIGNED。将此变量设置为空字符串以禁止源和副本之间的类型转换。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    有关基于行复制中适用于属性提升和降级的类型转换模式的更多信息,请参阅基于行复制:属性提升和降级。

  • replication_optimize_for_static_plugin_config

    命令行格式 --replication-optimize-for-static-plugin-config[={OFF&#124;ON}]
    引入版本 8.0.23
    系统变量 replication_optimize_for_static_plugin_config
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    使用共享锁,并避免不必要的锁获取,以提高半同步复制的性能。这个设置和 replication_sender_observe_commit_only 在副本数量增加时有帮助,因为锁争用会降低性能。在启用此系统变量时,半同步复制插件无法卸载,因此必须在卸载完成之前禁用该系统变量。

    可以在安装半同步复制插件之前或之后启用此系统变量,并且可以在复制运行时启用。半同步复制源服务器也可以通过启用此系统变量获得性能优势,因为它们使用与副本相同的锁定机制。

    当服务器上使用组复制时,可以启用replication_optimize_for_static_plugin_config。在这种情况下,当由于高工作负载而导致锁争用时,可能会提高性能。

  • replication_sender_observe_commit_only

    命令行格式 --replication-sender-observe-commit-only[={OFF&#124;ON}]
    引入版本 8.0.23
    系统变量 replication_sender_observe_commit_only
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    限制回调以提高半同步复制的性能。这个设置和replication_optimize_for_static_plugin_config在副本数量增加时有帮助,因为锁争用可能会降低性能。

    这个系统变量可以在安装半同步复制插件之前或之后启用,并且可以在复制运行时启用。半同步复制源服务器也可以通过启用这个系统变量获得性能优势,因为它们使用与副本相同的锁定机制。

  • report_host

    命令行格式 --report-host=host_name
    系统变量 report_host
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    在副本注册期间向源报告的副本的主机名或 IP 地址。此值将出现在源服务器的SHOW REPLICAS输出中。如果不希望副本向源注册自己,请将值保持未设置。

    注意

    仅仅从副本连接后的 TCP/IP 套接字中读取副本服务器的 IP 地址是不够的。由于 NAT 和其他路由问题,该 IP 可能无法用于从源或其他主机连接到副本。

  • report_password

    命令行格式 --report-password=name
    系统变量 report_password
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    在复制品注册期间向源报告的复制品的帐户密码。如果源使用 --show-replica-auth-info--show-slave-auth-info 启动,则此值将出现在源服务器上 SHOW REPLICAS 的输出中。

    尽管此变量的名称可能暗示相反,report_password 与 MySQL 用户权限系统无关,因此不一��(甚至可能不是)与 MySQL 复制用户帐户的密码相同。

  • report_port

    命令行格式 --report-port=port_num
    系统变量 report_port
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 [slave_port]
    最小值 0
    最大值 65535

    用于连接到复制品的 TCP/IP 端口号,在复制品注册期间向源报告。仅在复制品侦听非默认端口或源或其他客户端到复制品有特殊隧道时设置此选项。如果不确定,请不要使用此选项。

    此选项的默认值是实际使用的复制品端口号。这也是 SHOW REPLICAS 显示的默认值。

  • report_user

    命令行格式 --report-user=name
    系统变量 report_user
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    在复制品注册期间向源报告的复制品的帐户用户名。如果源使用 --show-replica-auth-info--show-slave-auth-info 启动,则此值将出现在源服务器上 SHOW REPLICAS 的输出中。

    尽管此变量的名称可能暗示相反,report_user 与 MySQL 用户权限系统无关,因此不一定(甚至可能不是)与 MySQL 复制用户帐户的名称相同。

  • rpl_read_size

    命令行格式 --rpl-read-size=#
    系统变量 rpl_read_size
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 8192
    最小值 8192
    最大值 4294959104
    单位 字节
    块大小 8192

    rpl_read_size 系统变量控制从二进制日志文件和中继日志文件中读取的最小数据量(以字节为单位)。如果这些文件的大量磁盘 I/O 活动影响了数据库的性能,增加读取大小可能会减少文件读取和 I/O 停顿,尤其是当文件数据当前未被操作系统缓存时。

    rpl_read_size 的最小和默认值为 8192 字节。该值必须是 4KB 的倍数。请注意,为从二进制日志和中继日志文件读取的每个线程分配了此值大小的缓冲区,包括源上的转储线程和副本上的协调器线程。因此,设置一个较大的值可能会影响服务器的内存消耗。

  • rpl_semi_sync_replica_enabled

    命令行格式 --rpl-semi-sync-replica-enabled[={OFF&#124;ON}]
    引入版本 8.0.26
    系统变量 rpl_semi_sync_replica_enabled
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    当在副本上安装了rpl_semi_sync_replicasemisync_replica.so库)插件以设置半同步复制时,rpl_semi_sync_replica_enabled 可用。如果安装了rpl_semi_sync_slave插件(semisync_slave.so库),则可以使用rpl_semi_sync_slave_enabled

    rpl_semi_sync_replica_enabled 控制着复制服务器上是否启用半同步复制。要启用或禁用插件,请将此变量分别设置为ONOFF(或 1 或 0)。默认值为OFF

    仅当安装了副本端半同步复制插件时才可用此变量。

  • rpl_semi_sync_replica_trace_level

    命令���格式 --rpl-semi-sync-replica-trace-level=#
    引入版本 8.0.26
    系统变量 rpl_semi_sync_replica_trace_level
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 32
    最小值 0
    最大值 4294967295

    当安装了rpl_semi_sync_replicasemisync_replica.so库)插件以设置半同步复制时,rpl_semi_sync_replica_trace_level 可用。如果安装了rpl_semi_sync_slave插件(semisync_slave.so库),则可用rpl_semi_sync_slave_trace_level

    rpl_semi_sync_replica_trace_level 控制副本服务器上半同步复制的调试跟踪级别。有关允许的值,请参阅rpl_semi_sync_master_trace_level

    仅当安装了副本端半同步复制插件时才可用此变量。

  • rpl_semi_sync_slave_enabled

    命令行格式 --rpl-semi-sync-slave-enabled[={OFF&#124;ON}]
    系统变量 rpl_semi_sync_slave_enabled
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔
    默认值 OFF

    当安装了rpl_semi_sync_slavesemisync_slave.so库)插件以设置半同步复制时,rpl_semi_sync_slave_enabled 可用。如果安装了rpl_semi_sync_replica插件(semisync_replica.so库),则可用rpl_semi_sync_replica_enabled

    rpl_semi_sync_slave_enabled 控制副本服务器上是否启用半同步复制。要启用或禁用插件,请将此变量设置为ONOFF(或分别为 1 或 0)。默认值为OFF

    仅当安装了副本端半同步复制插件时才可用此变量。

  • rpl_semi_sync_slave_trace_level

    命令行格式 --rpl-semi-sync-slave-trace-level=#
    系统变量 rpl_semi_sync_slave_trace_level
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 32
    最小值 0
    最大值 4294967295

    rpl_semi_sync_slave_trace_level 在安装了rpl_semi_sync_slavesemisync_slave.so库)插件的复制品上可用,用于设置半同步复制。如果安装了rpl_semi_sync_replica插件(semisync_replica.so库),则可用rpl_semi_sync_replica_trace_level

    rpl_semi_sync_slave_trace_level 控制复制品服务器上的半同步复制调试跟踪级别。有关允许的值,请参阅rpl_semi_sync_master_trace_level

    仅当安装了复制品端半同步复制插件时才可用。

  • rpl_stop_replica_timeout

    命令行格式 --rpl-stop-replica-timeout=#
    引入版本 8.0.26
    系统变量 rpl_stop_replica_timeout
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 31536000
    最小值 2
    最大值 31536000
    单位

    从 MySQL 8.0.26 开始,使用rpl_stop_replica_timeout代替rpl_stop_slave_timeout,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用rpl_stop_slave_timeout

    通过设置此变量,您可以控制STOP REPLICA在超时之前等待的时间长度(以秒为单位)。这可用于避免STOP REPLICA与使用不同客户端连接到复制品的其他 SQL 语句之间的死锁。

    rpl_stop_replica_timeout的最大值和默认值为 31536000 秒(1 年)。最小值为 2 秒。对此变量的更改将对后续的STOP REPLICA语句生效。

    此变量仅影响发出 STOP REPLICA 命令的客户端。当超时时,发出命令的客户端将返回一条错误消息,指示命令执行不完整。客户端停止等待复制 I/O(接收器)和 SQL(应用程序)线程停止,但复制线程继续尝试停止,并且 STOP REPLICA 命令仍然有效。一旦复制线程不再忙碌,STOP REPLICA 命令将被执行,副本将停止。

  • rpl_stop_slave_timeout

    命令行格式 --rpl-stop-slave-timeout=#
    已弃用 8.0.26
    系统变量 rpl_stop_slave_timeout
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 31536000
    最小值 2
    最大值 31536000
    单位

    从 MySQL 8.0.26 开始,rpl_stop_slave_timeout 已被弃用,应改用别名 rpl_stop_replica_timeout。在 MySQL 8.0.26 之前的版本中,请使用 rpl_stop_slave_timeout

    通过设置此变量,您可以控制 STOP REPLICA 在超时前等待的时间长度(以秒为单位)。这可用于避免在使用不同客户端连接到副本的其他 SQL 语句和 STOP REPLICA 之间发生死锁。

    rpl_stop_slave_timeout 的最大和默认值为 31536000 秒(1 年)。最小值为 2 秒。对此变量的更改将对后续的 STOP REPLICA 命令生效。

    此变量仅影响发出 STOP REPLICA 命令的客户端。当超时时,发出命令的客户端将返回一条错误消息,指示命令执行不完整。客户端停止等待复制 I/O(接收器)和 SQL(应用程序)线程停止,但复制线程继续尝试停止,并且 STOP REPLICA 指令仍然有效。一旦复制线程不再忙碌,STOP REPLICA 命令将被执行,副本将停止。

  • skip_replica_start

    命令行格式 --skip-replica-start[={OFF&#124;ON}]
    引入 8.0.26
    系统变量 skip_replica_start
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    从 MySQL 8.0.26 开始,应使用 skip_replica_start 替代 skip_slave_start,因为从该版本开始已弃用。在 MySQL 8.0.26 之前的版本中,请使用 skip_slave_start

    skip_replica_start 告诉复制服务器在启动服务器时不要启动复制 I/O(接收器)和 SQL(应用程序)线程。要稍后启动线程,请使用 START REPLICA 语句。

    此系统变量为只读,可以使用 PERSIST_ONLY 关键字或 @@persist_only 修饰符与 SET 语句一起设置。--skip-replica-start 命令行选项也设置此系统变量。您可以使用系统变量代替命令行选项,以允许通过 MySQL Server 的权限结构访问此功能,这样数据库管理员就不需要对操作系统有任何特权访问。

  • skip_slave_start

    命令行格式 --skip-slave-start[={OFF&#124;ON}]
    已弃用 8.0.26
    系统变量 skip_slave_start
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    从 MySQL 8.0.26 开始,skip_slave_start 已被弃用,应改用别名 skip_replica_start。在 MySQL 8.0.26 之前的版本中,请使用 skip_slave_start

    告诉复制服务器在启动服务器时不要启动复制 I/O(接收器)和 SQL(应用程序)线程。要稍后启动线程,请使用 START REPLICA 语句。

    此系统变量从 MySQL 8.0.24 版本开始可用。它是只读的,可以使用PERSIST_ONLY关键字或在SET语句中使用@@persist_only限定符来设置。--skip-slave-start命令行选项也会设置此系统变量。您可以使用系统变量代替命令行选项,以允许通过 MySQL 服务器的权限结构访问此功能,这样数据库管理员就不需要对操作系统具有任何特权访问。

  • slave_checkpoint_group

    命令行格式 --slave-checkpoint-group=#
    弃用 8.0.26
    系统变量 slave_checkpoint_group
    作用域 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 512
    最小值 32
    最大值 524280
    块大小 8

    从 MySQL 8.0.26 开始,slave_checkpoint_group已被弃用,应改用别名replica_checkpoint_group。在 MySQL 8.0.26 之前的版本中,请使用slave_checkpoint_group

    slave_checkpoint_group设置了多线程副本在调用检查点操作以更新其状态之前可以处理的最大事务数量,如SHOW REPLICA STATUS所示。设置此变量对未启用多线程的副本没有影响。设置此变量没有立即效果。变量的状态适用于所有后续的START REPLICA语句。

    以前,NDB Cluster 不支持多线程副本,对于此变量的设置被静默忽略。此限制在 MySQL 8.0.33 中解除。

    此变量与slave_checkpoint_period系统变量结合使用,当超过任一限制时,将执行检查点,并重置跟踪事务数量和自上次检查点以来经过的时间的计数器。

    该变量的最小允许值为 32,除非服务器是使用-DWITH_DEBUG构建的,此时最小值为 1。有效值始终是 8 的倍数;您可以将其设置为非 8 的倍数,但服务器在存储值之前会将其向下舍入到下一个较低的 8 的倍数。(例外: 调试服务器不执行此舍入操作。) 无论服务器是如何构建的,默认值为 512,最大允许值为 524280。

  • slave_checkpoint_period

    命令行格式 --slave-checkpoint-period=#
    已弃用 8.0.26
    系统变量 slave_checkpoint_period
    作用域 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 300
    最小值 1
    最大值 4294967295
    单位 毫秒

    截至 MySQL 8.0.26,slave_checkpoint_period已弃用,应改用replica_checkpoint_period;在 MySQL 8.0.26 之前,请使用slave_checkpoint_period

    slave_checkpoint_period设置了允许经过的最长时间(以毫秒为单位),在此时间内将调用检查点操作来更新多线程副本的状态,如SHOW REPLICA STATUS所示。设置此变量对未启用多线程的副本没有影响。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    以前,NDB Cluster 不支持多线程副本,对于这个变量的设置被静默忽略。这个限制在 MySQL 8.0.33 中被取消。

    此变量与slave_checkpoint_group系统变量结合使用,当超过任一限制时,将执行检查点并重置跟踪事务数量和自上次检查点以来经过的时间的计数器。

    该变量的最小允许值为 1,除非服务器是使用-DWITH_DEBUG构建的,此时最小值为 0。无论服务器是如何构建的,默认值为 300 毫秒,最大可能值为 4294967295 毫秒(约 49.7 天)。

  • slave_compressed_protocol

    命令行格式 --slave-compressed-protocol[={OFF&#124;ON}]
    已弃用 8.0.18
    系统变量 slave_compressed_protocol
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    slave_compressed_protocol 已被弃用,从 MySQL 8.0.26 开始,应改用别名 replica_compressed_protocol。在 MySQL 8.0.26 之前的版本中,请使用 slave_compressed_protocol

    slave_compressed_protocol 控制是否在源/副本连接协议上使用压缩,如果源和副本都支持。如果禁用此变量(默认情况下),连接将不被压缩。对此变量的更改将在后续连接尝试中生效;这包括在发出 START REPLICA 语句后,以及由正在运行的复制 I/O(接收器)线程进行的重新连接。

    二进制日志事务压缩(自 MySQL 8.0.20 起可用),由 binlog_transaction_compression 系统变量激活,也可用于节省带宽。如果将二进制日志事务压缩与协议压缩结合使用,协议压缩的作用机会较少,但仍可压缩标头以及未压缩的事件和事务有效载荷。有关二进制日志事务压缩的更多信息,请参见 Section 7.4.4.5, “Binary Log Transaction Compression”。

    自 MySQL 8.0.18 起,如果启用了 slave_compressed_protocol,它将优先于为 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 语句指定的任何 SOURCE_COMPRESSION_ALGORITHMS | MASTER_COMPRESSION_ALGORITHMS 选项。在这种情况下,如果源和副本都支持该算法,则连接到源使用 zlib 压缩。如果禁用了 slave_compressed_protocol,则 SOURCE_COMPRESSION_ALGORITHMS | MASTER_COMPRESSION_ALGORITHMS 的值适用。有关更多信息,请参见 Section 6.2.8, “Connection Compression Control”。

    从 MySQL 8.0.18 开始,此系统变量已被弃用。您应该期望它在将来的 MySQL 版本中被移除。请参阅配置传统连接压缩。

  • slave_exec_mode

    命令行格式 --slave-exec-mode=mode
    系统变量 slave_exec_mode
    范围 全局
    动态
    SET_VAR 提示适用
    类型 枚举
    默认值 IDEMPOTENT(NDB)STRICT(其他)
    有效值 STRICT``IDEMPOTENT

    从 MySQL 8.0.26 开始,slave_exec_mode 已被弃用,应改用别名 replica_exec_mode。在 MySQL 8.0.26 之前的版本中,请使用 slave_exec_mode

    slave_exec_mode 控制复制线程在复制过程中如何解决冲突和错误。IDEMPOTENT 模式导致重复键和找不到键错误的抑制;STRICT 表示不会发生这种抑制。

    IDEMPOTENT 模式适用于多源复制、循环复制和 NDB Cluster 复制的一些其他特殊复制场景。(有关更多信息,请参阅第 25.7.10 节,“NDB Cluster 复制:双向和循环复制”,以及第 25.7.12 节,“NDB Cluster 复制冲突解决”。)NDB Cluster 忽略为 slave_exec_mode 明确设置的任何值,并始终将其视为 IDEMPOTENT

    在 MySQL Server 8.0 中,STRICT 模式是默认值。

    设置此变量立即对所有复制通道生效,包括正在运行的通道。

    对于除了NDB之外的存储引擎,只有在您绝对确定可以安全忽略重复键错误和找不到键错误时,才应使用IDEMPOTENT模式。它旨在用于 NDB Cluster 的故障转移场景,其中使用了多源复制或循环复制,并不建议在其他情况下使用。

  • slave_load_tmpdir

    命令行格式 --slave-load-tmpdir=dir_name
    已弃用 8.0.26
    系统变量 slave_load_tmpdir
    范围 ��局
    动态
    SET_VAR 提示适用
    类型 目录名称
    默认值 --tmpdir 的值

    从 MySQL 8.0.26 开始,slave_load_tmpdir 已弃用,应改用别名replica_load_tmpdir。在 MySQL 8.0.26 之前的版本中,请使用slave_load_tmpdir

    slave_load_tmpdir 指定副本创建临时文件的目录名称。设置此变量立即对所有复制通道生效,包括正在运行的通道。变量值默认等于tmpdir系统变量的值,或者在未指定该系统变量时适用的默认值。

    当复制 SQL 线程复制LOAD DATA语句时,它会将要加载的文件从中继日志中提取到临时文件中,然后将这些文件加载到表中。如果源上加载的文件很大,则副本上的临时文件也很大。因此,建议使用此选项告诉副本将临时文件放在某个具有大量可用空间的文件系统中的目录中。在这种情况下,中继日志也很大,因此您可能还想设置relay_log系统变量以将中继日志放在该文件系统中。

    此选项指定的目录应位于基于磁盘的文件系统中(而不是基于内存的文件系统),以便用于复制LOAD DATA语句的临时文件可以在机器重新启动时保留。该目录也不应该是在系统启动过程中被操作系统清除的目录。但是,如果临时文件已被删除,则复制现在可以在重新启动后继续。

  • slave_max_allowed_packet

    命令行格式 --slave-max-allowed-packet=#
    已弃用 8.0.26
    系统变量 slave_max_allowed_packet
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 1073741824
    最小值 1024
    最大值 1073741824
    单位 字节
    块大小 1024

    从 MySQL 8.0.26 开始,slave_max_allowed_packet 已被弃用,应改用别名 replica_max_allowed_packet。在 MySQL 8.0.26 之前的版本中,请使用 slave_max_allowed_packet

    slave_max_allowed_packet 设置复制 SQL(应用程序)和 I/O(接收器)线程可以处理的最大数据包大小(以字节为单位)。设置此变量立即对所有复制通道生效,包括正在运行的通道。源可能写入比其 max_allowed_packet 设置更长的二进制日志事件,一旦添加事件头。slave_max_allowed_packet 的设置必须大于源上的 max_allowed_packet 设置,以确保使用基于行的复制进行大型更新时不会导致复制失败。

    此全局变量始终具有值,该值是 1024 的正整数倍;如果将其设置为非 1024 的值,则将其舍入到下一个最高的 1024 的倍数以进行存储或使用;将 slave_max_allowed_packet 设置为 0 会���致使用 1024。(在所有这些情况下都会发出截断警告。)默认值和最大值为 1073741824(1 GB);最小值为 1024。

  • slave_net_timeout

    命令行格式 --slave-net-timeout=#
    已弃用 8.0.26
    系统变量 slave_net_timeout
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 60
    最小值 1
    最大值 31536000
    单位

    从 MySQL 8.0.26 开始,slave_net_timeout 已被弃用,应改用别名 replica_net_timeout。在 MySQL 8.0.26 之前的版本中,请使用 slave_net_timeout

    slave_net_timeout 指定等待来自源的更多数据或心跳信号的秒数,然后副本认为连接已中断,中止读取,并尝试重新连接。设置此变量没有立即效果。变量的状态适用于所有后续的 START REPLICA 命令。

    默认值为 60 秒(一分钟)。超时后立即进行第一次重试。重试间隔由 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 语句的 SOURCE_CONNECT_RETRY | MASTER_CONNECT_RETRY 选项控制,重连尝试次数由 SOURCE_RETRY_COUNT | MASTER_RETRY_COUNT 选项限制。

    心跳间隔,用于防止在没有数据的情况下发生连接超时,由 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 语句的 SOURCE_HEARTBEAT_PERIOD | MASTER_HEARTBEAT_PERIOD 选项控制。心跳间隔默认为 slave_net_timeout 值的一半,并记录在副本的连接元数据存储库中,并显示在 replication_connection_configuration 性能模式表中。请注意,对于 slave_net_timeout 的值或默认设置的更改不会自动更改心跳间隔,无论是显式设置还是使用先前计算的默认值。如果更改了连接超时时间,您还必须发出 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 来调整心跳间隔至适当值,以确保它在连接超时之前发生。

  • slave_parallel_type

    命令行格式 --slave-parallel-type=value
    已弃用 8.0.26
    系统变量 slave_parallel_type
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 枚举
    默认值(≥ 8.0.27) LOGICAL_CLOCK
    默认值(≤ 8.0.26) DATABASE
    有效值 DATABASE``LOGICAL_CLOCK

    从 MySQL 8.0.26 开始,slave_parallel_type 已被弃用,应改用别名 replica_parallel_type。在 MySQL 8.0.26 之前的版本中,请使用 slave_parallel_type

    对于多线程副本(将replica_parallel_workersslave_parallel_workers设置为大于 0 的值的副本),slave_parallel_type指定了用于决定在副本上哪些事务允许并行执行的策略。该变量对于未启用多线程的副本没有影响。可能的值包括:

    • LOGICAL_CLOCK:在源头上属于同一二进制日志组提交的事务在副本上并行应用。事务之间的依赖关系基于它们的时间戳进行跟踪,以在可能的情况下提供额外的并行化。当设置了这个值时,可以在源头上使用binlog_transaction_dependency_tracking系统变量来指定在写入集可用的情况下,使用写入集代替时间戳进行并行化,如果写入集对事务提供了改进的结果。

    • DATABASE:更新不同数据库的事务并行应用。只有在数据被分区到多个独立并同时在源头上更新的数据库时,此值才合适。在副本上不得存在跨数据库约束,因为这样的约束可能会在副本上被违反。

    replica_preserve_commit_order=ONslave_preserve_commit_order=ON被设置时,只能使用LOGICAL_CLOCK。在 MySQL 8.0.27 之前,默认为DATABASE。从 MySQL 8.0.27 开始,默认情况下为副本服务器启用了多线程(默认为replica_parallel_workers=4),因此LOGICAL_CLOCK是默认值,并且设置replica_preserve_commit_order=ON也是默认值。

    当您的复制拓扑结构使用多级副本时,LOGICAL_CLOCK可能会导致每个副本距离源头越远时并行化效果减少。您可以通过在源头使用binlog_transaction_dependency_tracking来减少这种影响,以指定在可能的情况下使用写入集而不是时间戳进行并行化。

    当使用 binlog_transaction_compression 系统变量启用二进制日志事务压缩时,如果 replica_parallel_typeslave_parallel_type 设置为 DATABASE,则在调度事务之前将映射受事务影响的所有数据库。与未压缩的事务相比,使用 DATABASE 策略的二进制日志事务压缩可能会减少并行性,因为未压缩的事务会为每个事件映射并调度。

  • slave_parallel_workers

    命令行格式 --slave-parallel-workers=#
    弃用 8.0.26
    系统变量 slave_parallel_workers
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值(≥ 8.0.27) 4
    默认值(≤ 8.0.26) 0
    最小值 0
    最大值 1024

    从 MySQL 8.0.26 开始,slave_parallel_workers 已弃用,应改用别名 replica_parallel_workers。在 MySQL 8.0.26 之前的版本中,请使用 slave_parallel_workers

    slave_parallel_workers 启用副本上的多线程,并设置用于并行执行复制事务的应用程序线程数。当值大于 0 时,副本是具有指定数量的应用程序线程的多线程副本,还有一个协调器线程来管理它们。如果使用多个复制通道,则每个通道都有这个数量的线程。

    在 MySQL 8.0.27 之前,此系统变量的默认值为 0,因此默认情况下副本不是多线程的。从 MySQL 8.0.27 开始,默认值为 4,因此默认情况下副本是多线程的。

    当启用多线程时,支持事务的重试。当设置replica_preserve_commit_order=ONslave_preserve_commit_order=ON时,副本上的事务以与副本的中继日志中出现的顺序相同的顺序在副本上外部化。事务在应用程序线程之间分配的方式由replica_parallel_type(从 MySQL 8.0.26 开始)或slave_parallel_type(在 MySQL 8.0.26 之前)配置。从 MySQL 8.0.27 开始,这些系统变量也具有适用于多线程的默认值。

    要禁用并行执行,将replica_parallel_workers设置为 0,这将为副本提供一个单独的应用程序线程和没有协调器线程。在这种设置下,replica_parallel_typeslave_parallel_type以及replica_preserve_commit_orderslave_preserve_commit_order系统变量没有效果,并且被忽略。从 MySQL 8.0.27 开始,如果在副本上启用GTID_ONLY选项时禁用并行执行,副本实际上会使用一个并行工作者来利用无需访问文件位置即可重试事务的方法。使用一个并行工作者,replica_preserve_commit_orderslave_preserve_commit_order)系统变量也没有效果。

    设置replica_parallel_workers没有立即效果。变量的状态适用于所有后续的START REPLICA语句。

    以前,NDB Cluster 不支持多线程副本,静默地忽略了此变量的设置。这个限制在 MySQL 8.0.33 中解除。

  • slave_pending_jobs_size_max

    命令行格式 --slave-pending-jobs-size-max=#
    已弃用 8.0.26
    系统变量 slave_pending_jobs_size_max
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值(≥ 8.0.12) 128M
    默认值(8.0.11) 16M
    最小值 1024
    最大值 16EiB
    单位 字节
    块大小 1024

    从 MySQL 8.0.26 开始,slave_pending_jobs_size_max 已被弃用,应改用别名 replica_pending_jobs_size_max。在 MySQL 8.0.26 之前的版本中,请使用 slave_pending_jobs_size_max

    对于多线程复制,此变量设置了尚未应用的事件的接收器队列可用的最大内存量(以字节为单位)。设置此变量对未启用多线程的复制品没有影响。设置此变量不会立即生效。变量的状态适用于所有后续的 START REPLICA 命令。

    此变量的最小可能值为 1024 字节;默认值为 128MB。最大可能值为 18446744073709551615(16 exbibytes)。不是 1024 字节的精确倍数的值在存储之前会被舍入到下一个较低的 1024 字节的倍数。

    此变量的值是一个软限制,可以设置为匹配正常工作负载。如果异常大的事件超过此大小,事务将被保持,直到所有工作线程的队列为空,然后再处理。所有后续事务将被保持,直到大事务完成。

  • slave_preserve_commit_order

    命令行格式 --slave-preserve-commit-order[={OFF&#124;ON}]
    弃用 8.0.26
    系统变量 slave_preserve_commit_order
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值(≥ 8.0.27) ON
    默认值(≤ 8.0.26) OFF

    从 MySQL 8.0.26 开始,slave_preserve_commit_order 已被弃用,应改用别名 replica_preserve_commit_order。在 MySQL 8.0.26 之前的版本中,请使用 slave_preserve_commit_order

    对于多线程副本(将replica_parallel_workersslave_parallel_workers设置为大于 0 的值的副本),设置slave_preserve_commit_order=1确保事务在副本上以与它们在副本的中继日志中出现的顺序相同的顺序执行和提交。这可以防止在已从副本的中继日志执行的事务序列中出现间隙,并保留与源相同的事务历史(具有下面列出的限制)。此变量对未启用多线程的副本无效。

    在 MySQL 8.0.27 之前,此系统变量的默认值为OFF,意味着事务可能会按顺序提交。从 MySQL 8.0.27 开始,默认情况下为副本服务器启用了多线程(默认为replica_parallel_workers=4),因此slave_preserve_commit_order=ON是默认设置,设置slave_parallel_type=LOGICAL_CLOCK也是默认设置。同样从 MySQL 8.0.27 开始,如果将slave_parallel_workers设置为 1,则slave_preserve_commit_order的设置将被忽略,因为在这种情况下,事务的顺序仍然会被保留。

    截至 MySQL 8.0.18,设置slave_preserve_commit_order=ON要求在副本上启用二进制日志(log_bin)和副本更新日志(log_slave_updates),这是从 MySQL 8.0 开始的默认设置。从 MySQL 8.0.19 开始,在副本上设置slave_preserve_commit_order=ON不再需要启用二进制日志和副本更新日志,并且如果需要的话可以禁用。在所有版本中,设置slave_preserve_commit_order=ON要求将slave_parallel_type设置为LOGICAL_CLOCK,这在 MySQL 8.0.27 之前是默认设置。在更改slave_preserve_commit_orderslave_parallel_type的值之前,必须停止复制 SQL 线程(如果使用多个复制通道,则对所有复制通道的复制 SQL 线程都要停止)。

    slave_preserve_commit_order=OFF被设置时,这是默认设置,多线程复制的副本并行应用的事务可能会无序提交。因此,检查最近执行的事务并不能保证源端的所有先前事务在副本上已执行。副本的中继日志中执行的事务序列可能存在间隙的可能性。这对于使用多线程复制时的日志记录和恢复有影响。更多信息请参见 Section 19.5.1.34, “复制和事务不一致性”。

    slave_preserve_commit_order=ON被设置时,执行的工作线程会等待所有先前的事务提交后再进行提交。当一个线程在等待其他工作线程提交事务时,它会报告其状态为等待前面的事务提交。使用这种模式,多线程复制永远不会进入源端不在的状态。这支持将复制用于读取扩展。更多信息请参见 Section 19.4.5, “使用复制进行扩展”。

    注意

    • slave_preserve_commit_order=ON不会阻止源二进制日志位置滞后,其中Exec_master_log_pos落后于已执行事务的位置。请参阅 Section 19.5.1.34, “Replication and Transaction Inconsistencies”。

    • slave_preserve_commit_order=ON不会保留副本在其二进制日志上使用过滤器时的提交顺序和事务历史,例如--binlog-do-db

    • slave_preserve_commit_order=ON不会保留非事务性 DML 更新的顺序。这些更新可能会在中继日志中的先前事务之前提交,这可能导致从副本的中继日志中执行的事务序列中出现间隙。

    • 在 MySQL 8.0.19 之前的版本中,slave_preserve_commit_order=ON在对象不存在时不会保留带有IF EXISTS子句的语句的顺序。这些语句可能会在中继日志中的先前事务之前提交,这可能导致从副本的中继日志中执行的事务序列中出现间隙。

    • 如果使用基于语句的复制,并且事务性和非事务性存储引擎参与在源上回滚的非 XA 事务,可能会出现保留副本上提交顺序的限制。通常,在源上回滚的非 XA 事务不会被复制到副本,但在这种特殊情况下,该事务可能会被复制到副本。如果发生这种情况,没有二进制日志记录的多线程副本无法处理事务回滚,因此在这种情况下,副本上的提交顺序会与事务的中继日志顺序发生分歧。

  • slave_rows_search_algorithms

    命令行格式 --slave-rows-search-algorithms=value
    弃用 8.0.18
    系统变量 slave_rows_search_algorithms
    范围 全局
    动态
    SET_VAR提示适用
    类型 设置
    默认值 INDEX_SCAN,HASH_SCAN
    有效取值 TABLE_SCAN,INDEX_SCAN``INDEX_SCAN,HASH_SCAN``TABLE_SCAN,HASH_SCAN``TABLE_SCAN,INDEX_SCAN,HASH_SCAN(等同于 INDEX_SCAN,HASH_SCAN)

    在为基于行的日志记录和复制准备行批次时,此系统变量控制如何搜索匹配的行,特别是是否使用哈希扫描。现在已弃用此系统变量。默认设置 INDEX_SCAN,HASH_SCAN 对性能最佳,并在所有情况下都能正常工作。请参阅 Section 19.5.1.27, “Replication and Row Searches”。

  • slave_skip_errors

    命令行格式 --slave-skip-errors=name
    已弃用 8.0.26
    系统变量 slave_skip_errors
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 OFF
    有效值 OFF``[错误代码列表]``all``ddl_exist_errors

    从 MySQL 8.0.26 开始,slave_skip_errors 已弃用,应使用别名 replica_skip_errors。在 MySQL 8.0.26 之前的版本中,请使用 slave_skip_errors

    通常情况下,当副本出现错误时,复制过程会停止,这给了你机会手动解决数据不一致性。此变量使得复制 SQL 线程在语句返回变量值中列出的任何错误时继续复制。

  • replica_skip_errors

    命令行格式 --replica-skip-errors=name
    引入版本 8.0.26
    系统变量 replica_skip_errors
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 OFF
    有效值 OFF``[错误代码列表]``all``ddl_exist_errors

    从 MySQL 8.0.26 开始,应使用 replica_skip_errors 替代 slave_skip_errors,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用 slave_skip_errors

    通常情况下,当副本���现错误时,复制过程会停止,这给了你机会手动解决数据不一致性。此变量使得复制 SQL 线程在语句返回变量值中列出的任何错误时继续复制。

  • slave_sql_verify_checksum

    命令行格式 --slave-sql-verify-checksum[={OFF&#124;ON}]
    已弃用 8.0.26
    系统变量 slave_sql_verify_checksum
    范围 全局
    动态
    SET_VAR Hint Applies
    类型 布尔值
    默认值 ON

    从 MySQL 8.0.26 开始,slave_sql_verify_checksum 已弃用,应改用别名 replica_sql_verify_checksum。在 MySQL 8.0.26 之前的版本中,请使用 slave_sql_verify_checksum

    slave_sql_verify_checksum 导致复制 SQL 线程使用从中继日志读取的校验和来验证数据。在出现不匹配时,副本将停止并显示错误。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    注意

    复制 I/O(接收器)线程在从网络接收事件时始终尽可能读取校验和。

  • slave_transaction_retries

    命令行格式 --slave-transaction-retries=#
    已弃用 8.0.26
    系统变量 slave_transaction_retries
    范围 全局
    动态
    SET_VAR Hint Applies
    类型 整数
    默认值 10
    最小值 0
    最大值(64 位平台) 18446744073709551615
    最大值(32 位平台) 4294967295

    从 MySQL 8.0.26 开始,slave_transaction_retries 已弃用,应改用别名 replica_transaction_retries。在 MySQL 8.0.26 之前的版本中,请使用 slave_transaction_retries

    slave_transaction_retries 设置单线程或多线程副本上的复制 SQL 线程在停止之前自动重试失败事务的最大次数。设置此变量立即对所有复制通道生效,包括正在运行的通道。默认值为 10。将变量设置为 0 会禁用事务的自动重试。

    如果复制 SQL 线程由于 InnoDB 死锁或因事务执行时间超过 InnoDBinnodb_lock_wait_timeoutNDBTransactionDeadlockDetectionTimeoutTransactionInactiveTimeout 而无法执行事务时,它会在停止并报错之前自动重试 slave_transaction_retries 次。具有非临时错误的事务不会被重试。

    Performance Schema 表 replication_applier_status 显示了每个复制通道上发生的重试次数,在 COUNT_TRANSACTIONS_RETRIES 列中。Performance Schema 表 replication_applier_status_by_worker 显示了单线程或多线程副本上各个应用程序线程对事务重试的详细信息,并标识导致最后一个事务和当前正在进行的事务重新尝试的错误。

  • slave_type_conversions

    命令行格式 --slave-type-conversions=set
    弃用 8.0.26
    系统变量 slave_type_conversions
    范围 全局
    动态
    SET_VAR 提示适用
    类型 集合
    默认值
    有效值 ALL_LOSSY``ALL_NON_LOSSY``ALL_SIGNED``ALL_UNSIGNED

    从 MySQL 8.0.26 开始,slave_type_conversions 已被弃用,应改用别名 replica_type_conversions。在 MySQL 8.0.26 之前的版本中,请使用 slave_type_conversions

    slave_type_conversions 控制着在使用基于行的复制时副本上生效的类型转换模式。其值是一个由逗号分隔的零个或多个元素的集合:ALL_LOSSYALL_NON_LOSSYALL_SIGNEDALL_UNSIGNED。将此变量设置为空字符串以禁止源和副本之间的类型转换。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    有关适用于基于行的复制中属性提升和降级的类型转换模式的更多信息,请参阅基于行的复制:属性提升和降级。

  • sql_replica_skip_counter

    引入版本 8.0.26
    系统变量 sql_replica_skip_counter
    作用域 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 4294967295

    从 MySQL 8.0.26 开始,使用 sql_replica_skip_counter 代替 sql_slave_skip_counter,后者从该版本开始已被弃用。在 MySQL 8.0.26 之前的版本中,请使用 sql_slave_skip_counter

    sql_replica_skip_counter 指定副本应跳过的源事件数。设置该选项没有立即效果。该变量适用于下一个 START REPLICA 语句;下一个 START REPLICA 语句还会将值更改回 0。当此变量设置为非零值且配置了多个复制通道时,START REPLICA 语句只能与 FOR CHANNEL *channel* 子句一起使用。

    该选项与基于 GTID 的复制不兼容,在设置gtid_mode=ON时不能将其设置为非零值。如果在使用 GTIDs 时需要跳过事务,请改用源端的gtid_executed。如果已经在复制通道上启用了 GTID 分配,使用CHANGE REPLICATION SOURCE TO语句的ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS选项,sql_replica_skip_counter可用。请参见第 19.1.7.3 节,“跳过事务”。

    重要

    如果跳过设置该变量指定的事件数量会导致复制品从事件组中间开始,那么复制品将继续跳过,直到找到下一个事件组的开头并从那一点开始。更多信息,请参见第 19.1.7.3 节,“跳过事务”。

  • sql_slave_skip_counter

    已弃用 8.0.26
    系统变量 sql_slave_skip_counter
    作用范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 4294967295

    从 MySQL 8.0.26 开始,sql_slave_skip_counter已弃用,应改用别名sql_replica_skip_counter。在 MySQL 8.0.26 之前的版本中,请使用sql_slave_skip_counter

    sql_slave_skip_counter指定复制品应该跳过的源事件数量。设置该选项没有立即效果。该变量适用于下一个START REPLICA语句;下一个START REPLICA语句也会将值更改回 0。当该变量设置为非零值且配置了多个复制通道时,START REPLICA语句只能与FOR CHANNEL *channel*子句一起使用。

    此选项与基于 GTID 的复制不兼容,在设置gtid_mode=ON时不能设置为非零值。如果在使用 GTIDs 时需要跳过事务,请改用源端的gtid_executed。如果已经在复制通道上启用了 GTID 分配,使用CHANGE REPLICATION SOURCE TO语句的ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS选项,可以使用sql_slave_skip_counter。参见第 19.1.7.3 节,“跳过事务”。

    重要提示

    如果通过设置此变量跳过指定数量的事件会导致副本在事件组中间开始,副本将继续跳过,直到找到下一个事件组的开头并从那里开始。有关更多信息,请参见第 19.1.7.3 节,“跳过事务”。

  • sync_master_info

    命令行格式 --sync-master-info=#
    已弃用 8.0.26
    系统变量 sync_master_info
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 10000
    最小值 0
    最大值 4294967295

    从 MySQL 8.0.26 开始,sync_master_info已被弃用,应改用别名sync_source_info。在 MySQL 8.0.26 之前的版本中,请使用sync_master_info

    sync_master_info指定副本在更新连接元数据存储库之前的事件数量。当连接元数据存储库存储为InnoDB表时(从 MySQL 8.0 开始默认),在此事件数量之后进行更新。如果连接元数据存储库存储为文件(从 MySQL 8.0 开始不推荐使用),副本在此事件数量之后将其master.info文件同步到磁盘(使用fdatasync())。默认值为 10000,零值表示存储库永远不会更新。设置此变量立即对所有复制通道生效,包括正在运行的通道。

  • sync_relay_log

    命令行格式 --sync-relay-log=#
    系统变量 sync_relay_log
    范围 全局
    动态
    SET_VAR Hint Applies
    类型 整数
    默认值 10000
    最小值 0
    最大值 4294967295

    如果此变量的值大于 0,则 MySQL 服务器在每写入sync_relay_log事件到中继日志后将其中继日志同步到磁盘(使用fdatasync())。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    sync_relay_log设置为 0 会导致不对磁盘进行同步;在这种情况下,服务器依赖操作系统定期刷新中继日志的内容,就像对任何其他文件一样。

    选择值为 1 是最安全的选择,因为在意外停机时,您最多只会丢失一个中继日志事件。然而,这也是最慢的选择(除非磁盘具有带电池备份缓存,这样同步会非常快)。有关在复制品上设置的组合对于意外停机最具弹性的信息,请参阅第 19.4.2 节,“处理复制品的意外停机”。

  • sync_relay_log_info

    命令行格式 --sync-relay-log-info=#
    已弃用 8.0.34
    系统变量 sync_relay_log_info
    范围 全局
    动态
    SET_VAR Hint Applies
    类型 整数
    默认值 10000
    最小值 0
    最大值 4294967295

    复制品更新应用程序元数据存储库之后的事务数。当应用程序元数据存储库存储为一个InnoDB表(MySQL 8.0 及以后版本的默认值),它在每个事务之后更新,此系统变量将被忽略。如果应用程序元数据存储库存储为一个文件(MySQL 8.0 中已弃用),则复制品在此数量的事务之后将其relay-log.info文件同步到磁盘(使用fdatasync())。0(零)表示文件内容仅由操作系统刷新。设置此变量立即对所有复制通道生效,包括正在运行的通道。

    由于存储应用程序元数据为文件已被弃用,此变量也已被弃用;从 MySQL 8.0.34 开始,服务器在设置或读取其值时会发出警告。您应该期望sync_relay_log_info在将来的 MySQL 版本中被移除,并立即迁移可能依赖它的应用程序。

  • sync_source_info

    命令行格式 --sync-source-info=#
    引入版本 8.0.26
    系统变量 sync_source_info
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 10000
    最小值 0
    最大值 4294967295

    从 MySQL 8.0.26 开始,使用 sync_source_info 替代从该版本开始已弃用的 sync_master_info。在 MySQL 8.0.26 之前的版本中,请使用 sync_source_info

    sync_source_info 指定了副本更新连接元数据存储库之后的事件数量。当连接元数据存储库存储为 InnoDB 表时(从 MySQL 8.0 开始默认),在此事件数量之后进行更新。如果连接元数据存储库存储为文件(从 MySQL 8.0 开始已弃用),则副本在此事件数量之后将其 master.info 文件同步到磁盘(使用 fdatasync())。默认值为 10000,零值表示存储库永远不会更新。设置此变量立即对所有复制通道生效,包括正在运行的通道。

  • terminology_use_previous

    命令行格式 --terminology-use-previous=#
    引入版本 8.0.26
    系统变量 terminology_use_previous
    范围 全局,会话
    动态
    SET_VAR 提示适用
    类型 枚举
    默认值 NONE
    有效值 NONE``BEFORE_8_0_26

    在 MySQL 8.0.26 中,对包含术语 masterslavemts(代表“多线程从属”)的仪表命名进行了不兼容的更改,分别更改为 sourcereplicamta(代表“多线程应用程序”)。如果这些不兼容的更改影响到您的应用程序,请将 terminology_use_previous 系统变量设置为 BEFORE_8_0_26,以便 MySQL Server 使用前述列表中指定对象的旧版本名称。这样一来,依赖于旧名称的监控工具将继续工作,直到它们可以更新为使用新名称。

    terminology_use_previous系统变量设置为会话范围以支持个别用户,或者设置为全局范围以成为所有新会话的默认值。当使用全局范围时,慢查询日志包含旧版本的名称。

    受影响的仪表化名称列在以下列表中。terminology_use_previous系统变量仅影响这些项目。它不影响在 MySQL 8.0.26 中引入的系统变量、状态变量和命令行选项的新别名,当设置时仍然可以使用这些别名。

    • 仪表化锁(互斥锁),在具有前缀wait/synch/mutex/mutex_instancesevents_waits_*性能模式表中可见

    • 读/写锁,在具有前缀wait/synch/rwlock/rwlock_instancesevents_waits_*性能模式表中可见

    • 仪表化条件变量,在具有前缀wait/synch/cond/cond_instancesevents_waits_*性能模式表中可见

    • 仪表化内存分配,在具有前缀memory/sql/memory_summary_*性能模式表中可见

    • 线程名称,在具有前缀thread/sql/threads性能模式表中可见

    • 线程阶段,在具有前缀stage/sql/events_stages_*性能模式表中可见,在threadsprocesslist性能模式表中没有前缀,在SHOW PROCESSLIST语句的输出中,在信息模式processlist表中,在慢查询日志中

    • 线程命令,在具有前缀statement/com/events_statements_history*events_statements_summary_*_by_event_name性能模式表中可见,在threadsprocesslist性能模式表中没有前缀,在SHOW PROCESSLIST语句的输出中,在信息模式processlist表中,在SHOW REPLICA STATUS语句的输出中

posted @ 2024-06-23 12:24  绝不原创的飞龙  阅读(4)  评论(0编辑  收藏  举报