原文:docs.oracle.com/javase/tutorial/reallybigindex.html
原文:dev.mysql.com/doc/refman/8.0/en/channels-commands-single-channel.html
19.2.2.1 单通道操作命令
要使MySQL 复制操作使用单个复制通道,请在以下复制语句中使用FOR CHANNEL *channel* 子句:
将复制源更改为
将主机更改为
启动REPLICA(或在MySQL 8.0.22 之前启动SLAVE)
STOP REPLICA(或MySQL 8.0.22 之前的STOP SLAVE)
查看中继日志事件
闪存中继日志
SHOW REPLICA STATUS(或在MySQL 8.0.22 之前显示从属状态)
RESET REPLICA(或MySQL 8.0.22 之前的RESET SLAVE)
以下函数具有通道参数。
MASTER_POS_WAIT()
SOURCE_POS_WAIT()
group_replication_recovery 通道上不允许使用以下语句。
启动副本
停止复制
group_replication_applier 通道上不允许使用以下语句。
启动副本
停止复制
显示副本状态
现在group_replication_applier 通道上允许FLUSH RELAY LOGS,但如果在应用事务时收到请求,则该请求将在事务完成后执行。请求者必须等待交易完成并轮换。此行为可以防止事务拆分,而这在组复制中是不允许的。
原文:dev.mysql.com/doc/refman/8.0/en/channels-with-prev-replication.html
19.2.2.2 与先前复制语句的兼容性
如果副本具有多个通道并且未指定FOR CHANNEL *channel* 选项,则有效语句通常适用于所有可用通道,但有一些特定的例外。
例如,以下语句在除某些组复制通道之外的所有通道上都可以正常工作。
START REPLICA 启动除group_replication_recovery 和group_replication_applier 通道之外的所有通道的复制线程。
STOP REPLICA 停止除group_replication_recovery 和group_replication_applier 通道之外的所有通道的复制线程。
SHOW REPLICA STATUS 报告除group_replication_applier 通道之外的所有通道的状态。
RESET REPLICA 重置所有通道。
警告
请谨慎使用RESET REPLICA。此语句删除所有现有通道,清除中继日志文件,并仅重新创建默认通道。
某些文案声明可能不适用于所有渠道。此场景会生成错误1964 副本有多个通道。请指定通道名称作为参数。以下语句和函数在多源复制拓扑中使用时会生成此错误,并且未使用FOR CHANNEL *channel* 选项来指定要操作的通道。
查看中继日志事件
将复制源更改为
将主机更改为
MASTER_POS_WAIT()
SOURCE_POS_WAIT()
请注意,在单源复制拓扑中,始终存在一个默认通道,其中语句和函数的行为与以前版本的MySQL 中相同。
翻译:dev.mysql.com/doc/refman/8.0/en/channels-startup-options.html
19.2.2.3 启动选项和复制通道
本节介绍受添加复制通道影响的启动选项。
使用复制通道时,master_info_repository 和relay_log_info_repository 系统变量必须设置为FILE。在MySQL 8.0 中,不推荐使用FILE 设置,而TABLE 是默认设置,因此可以省略这些系统变量。从MySQL 8.0.23 开始,您应该忽略它们,因为从该版本开始不推荐使用它们。如果这些系统变量设置为FILE,尝试向副本添加更多源将导致ER_SLAVE_NEW_CHANNEL_WRONG_REPOSITORY 错误。
以下启动选项现在会影响所有复制拓扑中的通道。
–log-replica-updates 或–log-slave-updates
副本接收到的所有事务(甚至来自多个源)都会写入二进制日志。
–中继日志清除
配置后,每个通道都会自动清除自己的中继日志。
–replica-transaction-retries 或–slave-transaction-retries
所有通道上的所有应用程序线程上都可以发生指定次数的事务重试。
–skip-replica-start 或–skip-slave-start (或Skip_replica_start 或Skip_slave_start 系统变量设置)
任何通道上都不会启动复制线程。
–replica-skip-errors 或–slave-skip-errors
继续执行并跳过所有通道的错误。
以下启动选项设置适用于每个通道。这些是mysqld 启动选项,因此它们适用于每个通道。
–max-relay-log-size=*大小*
当达到此限制时,每个通道一个中继日志文件的最大大小将轮换。
–relay-log-space-limit=*大小*
每个单独通道的所有中继日志总大小的上限。这些日志的总大小限制为*N* 个通道的relay_log_space_limit * *N*。
–replica-Parallel-workers=*值* 或–slave-Parallel-workers=*值*
每个通道的复制应用程序线程数。
副本检查点组或从属检查点组
每个接收线程等待每个源的时间量。
–relay-log-index=文件名
每个通道中继日志索引文件的基本名称。请参见复制通道命名约定。
–relay-log=文件名
表示每个通道中继日志文件的基本名称。请参见复制通道命名约定。
–replica-net-timeout=N 或–slave-net-timeout=N
该值是按通道设置的,因此每个通道将等待*N* 秒来检查是否有任何丢失的连接。
–replica-skip-counter=N 或–slave-skip-counter=N
该值是按通道设置的,因此每个通道将跳过源中的*N* 个事件。
原文:dev.mysql.com/doc/refman/8.0/en/channels-naming-conventions.html
19.2.2.4 复制通道命名约定
本节介绍复制通道如何影响命名约定。
每个复制通道都有一个唯一的名称,最大长度为64 个字符,并且不区分大小写。由于通道名称用于复制的应用程序元数据存储库表中,因此这些名称的字符集始终为UTF-8。虽然您通常可以自由为频道选择任何名称,但以下名称是保留的:
组复制应用程序
组复制_恢复
您为复制通道选择的名称还会影响多源复制的中继日志和索引文件的名称。每个通道的中继日志和索引文件的命名格式为*relay_log_basename*-*channel*。xxxxx
x,其中*relay_log_basename是使用relay_log系统变量指定的基本名称,channel*是该文件中记录的通道的名称。如果未指定relay_log系统变量,则使用默认文件名,其中还包括通道名称。
19.2.3 复制线程
原文:dev.mysql.com/doc/refman/8.0/en/replication-threads.html
19.2.3.1 监控复制主线程
19.2.3.2 监视复制应用程序工作线程
MySQL 复制功能是使用以下类型的线程实现的:
二进制日志转储线程。 当副本连接并将二进制日志的内容发送到副本时,源代码会创建一个线程。在源码的SHOW PROCESSLIST输出中可以识别出该线程为Binlog Dump线程。
复制I/O 接收线程。当在副本服务器上发出START REPLICA 语句时,副本会创建一个I/O(接收器)线程,该线程连接到源并请求源发送二进制记录的更新。
复制接收器线程读取源的二进制日志转储线程发送的更新(请参阅上一项)并将它们复制到构成副本中继日志的本地文件。
该线程的状态在SHOW REPLICA STATUS 的输出中显示为Slave_IO_running。
复制SQL 应用程序线程。如果plica_Parallel_workers(在MySQL 8.0.26及更早版本中,使用slave_Parallel_workers)等于0,则副本会创建一个SQL(应用程序)线程来读取复制接收器线程写入的中继日志并执行其包含的事务。如果plica_Parallel_workers 为*N*=1,则有N 个应用程序线程和一个协调器线程,该协调器线程调度顺序从中继日志读取事务并应用它们的工作线程。每个工作线程应用协调器分配的事务。
您可以通过将系统变量replica_Parallel_workers(MySQL 8.0.26及更高版本)或slave_Parallel_workers(MySQL 8.0.26及更早版本)设置为大于0的值来进一步并行化副本上的任务。当您执行此操作时,副本会创建指定数量的工作线程来应用事务,并创建一个协调器线程来从中继日志读取事务并将其分发到工作线程。 plica_Parallel_workers (slave_Parallel_workers) 设置为大于0 的值的副本称为多线程副本。如果使用多个复制通道,则每个通道使用此变量指定的线程数。
消息
从NDB 版本8.0.33 开始,MySQL Cluster 支持多线程复制。 (以前,NDB 默默地忽略了replica_Parallel_workers 设置。)有关更多信息,请参阅第25.7.11 节“使用多线程应用程序的MySQL 集群复制”。
原文:dev.mysql.com/doc/refman/8.0/en/replication-threads-monitor-main.html
19.2.3.1 监控复制主线程
SHOW PROCESSLIST 语句提供有关源和副本上发生的情况的信息。有关源状态的更多信息,请参阅复制源线程状态。有关副本状态的信息,请参阅第10.14.5 节“复制I/O(接收器)线程状态(线程状态)”和第10.14.6 节“复制SQL 线程状态”。
以下示例显示了SHOW PROCESSLIST 输出中显示的三个主要复制线程:二进制日志转储线程、复制I/O(接收器)线程和复制SQL(应用程序)线程。
以下是源服务器上SHOW PROCESSLIST 的输出:
mysql 显示进程列表\\G
************************** 1\\. 行****************** * **********
ID: 2
用户: root
主机: 本地主机:32931
db: 空
Command: 二进制日志转储
小时: 94
State: 正在发送所有binlog到slave并等待binlog发送。
我会更新
信息: NULL
这里,线程2是为连接的副本提供服务的Binlog Dump线程。状态信息表明所有未完成的更新已发送到副本,源正在等待进一步的更新发生。如果在源服务器上没有看到Binlog Dump 线程,则意味着复制未运行,这意味着当前没有连接的副本。
以下是副本服务器上SHOW PROCESSLIST 的输出:
mysql 显示进程列表\\G
************************** 1\\. 行****************** * **********
ID: 10
user: 系统用户
主机:
db: 空
Command: 连接
小时: 11
State: 等待主机发送事件
信息: NULL
************************** 2\\. 行****************** * **********
ID: 11
user: 系统用户
主机:
db: 空
Command: 连接
小时: 11
State: 读取所有等待从站I/O 的中继日志。
线程来更新它
信息: NULL
状态信息显示线程10 是与源服务器通信的复制I/O(接收器)线程,线程11 是处理保存到中继日志的更新的复制SQL(应用程序)线程。当SHOW PROCESSLIST 运行时,两个线程都处于空闲状态,等待进一步的更新。
时间列中的值表示副本相对于源的延迟。请参阅第A.14 节“MySQL 8.0 常见问题解答:复制”。如果二进制日志转储线程在足够长的时间内没有任何活动,则源确定副本未连接。对于其他客户端连接,这些超时取决于net_write_timeout和net_retry_count的值。有关这些值的更多信息,请参阅服务器系统变量。
showreplicastatus 语句提供有关副本服务器上的复制过程的附加信息。请参阅“检查复制状态”。
原文:dev.mysql.com/doc/refman/8.0/en/replication-threads-monitor-worker.html
19.2.3.2 监视复制应用程序工作线程
对于多线程复制,性能模式表replication_applier_status_by_coordinator 和replication_applier_status_by_worker 分别显示复制的协调器线程和应用程序工作线程的状态信息。对于具有多个通道的副本,会识别每个通道的线程。
当详细程度配置为显示信息性消息时,多线程复制协调器线程会定期将统计信息打印到复制的错误日志中。统计信息最多每120 秒打印一次,具体取决于协调器线程分配给应用程序工作线程的事件数量。该消息列出了关联复制通道或默认复制通道(未命名)的以下统计信息:
已过去的秒数
当前时间与上次将此信息打印到错误日志中的时间之间的差异(以秒为单位)。
指定事件
自协调器线程启动以来,协调器线程已为所有应用程序工作线程排队的事件总数。
工作队列填充超出限制级别
当前在应用程序工作线程中排队的事件数量超过溢出级别。此级别设置为16384 个事件的最大队列长度的90%。如果该值为零,则应用程序工作线程未以其能力运行。
由于工作队列已满而等待
由于应用程序工作线程队列已满,协调器线程等待计划事件的次数。如果该值为零,则任何应用程序工作线程都不会耗尽容量。
由于总大小较大,请等待
协调器线程因达到replica_pending_jobs_size_max 或slave_pending_jobs_size_max 限制而等待调度事件的次数。此系统变量设置应用程序工作线程队列可用于保存尚未应用的事件的最大内存量(以字节为单位)。如果异常大的事件超过此大小,则事务将被保留,直到所有应用程序工作线程的队列为空,然后再进行处理。所有后续交易都会被保留,直到大交易完成。
等待时钟争用
由于事件所依赖的事务尚未提交,协调线程等待计划事件的纳秒数。如果replica_parallel_type 或slave_parallel_type 设置为DATABASE(而不是LOGICAL_CLOCK),则该值始终为0。
等待工人被占用(计数)
对于默认复制通道,中继日志文件名的默认格式为*host_name*-relay-bin.*nnnnnn*。其中*host_name 是复制服务器主机的名称,nnnnnn 是序列号。连续的中继日志文件是使用从000001 开始的连续序列号创建的。对于非默认复制通道,基本名称为*host_name*-relay-bin-*channel*。其中channel*是中继日志中记录的复制通道的名称。
复制使用索引文件来跟踪当前正在使用哪些中继日志文件。默认中继日志索引文件名为*host_name*-relay-bin.index,非默认复制通道使用*host_name*-relay-bin-*channel*.index。
默认的中继日志文件和中继日志索引文件名和位置可以分别通过relay_log和relay_log_index系统变量覆盖(请参见第19.1.6节“复制和二进制日志选项和变量”)。
如果复制使用默认的基于主机的中继日志文件名,并且您在设置复制后更改复制主机名,则会出现“无法打开中继日志”和“执行期间未找到目标日志”错误消息,并且复制可能会失败。 “初始化中继日志”。这是一个已知问题(请参阅错误#2122)。如果您预计复制主机名将来可能会更改(例如,如果在复制上将网络配置为允许使用DHCP 更改主机名),则您可以使用变量明确指定中继。要完全避免此问题,请使用第一次设置复制日志文件名。这使得该名称不受服务器主机名更改的影响。
如果开始复制后出现问题,一种解决方法是停止复制服务器,将旧中继日志索引文件的内容附加到新文件,然后重新启动复制。在Unix 系统上,可以按如下方式完成此操作:
$ cat *新中继日志名称*.index *旧中继日志名称*.index
$ mv *旧中继日志名称*.index *新中继日志名称*.index
复制服务器在以下情况下创建:
建一个新的中继日志文件:
每次复制 I/O(接收器)线程启动时。
当日志被刷新时(例如,使用FLUSH LOGS或mysqladmin flush-logs)。
当当前中继日志文件的大小变得太大时,判定如下:
如果max_relay_log_size的值大于 0,则为最大中继日志文件大小。
如果max_relay_log_size的值为 0,则max_binlog_size确定最大中继日志文件大小。
复制 SQL(应用程序)线程在执行完文件中的所有事件并不再需要该文件时会自动删除每个中继日志文件。没有显式的机制用于删除中继日志,因为复制 SQL 线程会负责执行此操作。然而,FLUSH LOGS会旋转中继日志,影响复制 SQL 线程何时删除它们。
译文:dev.mysql.com/doc/refman/8.0/en/replica-logs-status.html
19.2.4.2 复制元数据存储库
复制服务器创建两个复制元数据存储库,连接元数据存储库和应用程序元数据存储库。复制元数据存储库在复制服务器关闭时保留。如果使用基于二进制日志文件位置的复制,则在复制重新启动时,它会读取这两个存储库,以确定它以前在读取源的二进制日志和处理自己的中继日志方面进行了多远。如果使用基于 GTID 的复制,则复制不会使用复制元数据存储库进行此目的,但确实需要其中包含的其他元数据。
复制的连接元数据存储库包含复制 I/O(接收器)线程需要连接到复制源服务器并从源的二进制日志中检索事务的信息。该存储库中的元数据包括连接配置、复制用户帐户详细信息、连接的 SSL 设置,以及复制接收器线程当前正在从源的二进制日志中读取的文件名和位置。
复制的应用程序元数据存储库包含复制 SQL(应用程序)线程需要读取并应用来自复制的中继日志的事务的信息。该存储库中的元数据包括复制应用程序线程已执行中继日志中的事务的文件名和位置,以及源二进制日志中的等效位置。它还包括应用事务过程的元数据,例如工作线程数和通道的PRIVILEGE_CHECKS_USER帐户。
连接元数据存储库写入mysql系统模式中的slave_master_info表中,而应用程序元数据存储库写入mysql系统模式中的slave_relay_log_info表中。如果mysqld无法初始化用于复制元数据存储库的表,则会发出警告消息,但允许复制继续启动。当从不支持使用表作为存储库的版本升级到支持表的版本时,最有可能发生这种情况。
重要
不要尝试手动更新或插入mysql.slave_master_info或mysql.slave_relay_log_info表中的行。这样做可能导致未定义的行为,并且不受支持。在复制正在进行时,不允许执行需要对slave_master_info和slave_relay_log_info表中的任一表或两个表进行写锁定的任何语句(尽管允许随时执行仅执行读取的语句)。
对于连接元数据存储库表mysql.slave_master_info的访问权限应该限制在数据库管理员,因为它包含用于连接到源的复制用户帐户名和密码。使用受限访问模式来保护包含此表的数据库备份。从 MySQL 8.0.21 开始,您可以从连接元数据存储库中清除复制用户帐户凭据,并始终使用START REPLICA语句或START GROUP_REPLICATION语句提供它们。这种方法意味着复制通道始终需要操作员干预才能重新启动,但帐户名和密码不会记录在复制元数据存储库中。
RESET REPLICA会清除复制元数据存储库中的数据,但不包括复制连接参数(取决于 MySQL Server 版本)。有关详细信息,请参阅RESET REPLICA的描述。
从 MySQL 8.0.27 开始,您可以在CHANGE REPLICATION SOURCE TO语句上设置GTID_ONLY选项,以阻止复制通道将文件名和文件位置持久化到复制元数据存储库中。这样可以避免在 GTID 基础复制实际上不需要它们的情况下对表进行写入和读取。使用GTID_ONLY设置时,当副本队列和应用程序在事务中排队和应用事件,或者当复制线程停止和启动时,连接元数据存储库和应用程序元数据存储库不会被更新。文件位置在内存中进行跟踪,并且如果需要,可以使用SHOW REPLICA STATUS语句查看。复制元数据存储库仅在以下情况下同步:
当发出CHANGE REPLICATION SOURCE TO语句时。
当发出RESET REPLICA语句时。RESET REPLICA ALL会删除而不是更新存储库,因此它们会隐式同步。
当初始化复制通道时。
如果将复制元数据存储库从文件移动到表中。
在 MySQL 8.0 之前,要将复制元数据存储库创建为表,需要在服务器启动时指定master_info_repository=TABLE和relay_log_info_repository=TABLE。否则,存储库将被创建为数据目录中的文件,命名为master.info和relay-log.info,或者使用–master-info-file选项和relay_log_info_file系统变量指定的替代名称和位置。从 MySQL 8.0 开始,默认情况下将复制元数据存储库创建为表,并且所有这些系统变量的使用已被弃用。
mysql.slave_master_info和mysql.slave_relay_log_info表是使用InnoDB事务存储引擎创建的。对应用程序元数据存储库表的更新与事务一起提交,这意味着记录在该存储库中的副本进度信息始终与已应用于数据库的内容一致,即使在发生意外服务器停机的情况下也是如此。有关在副本上设置的组合对于意外停机最具弹性的信息,请参阅 Section 19.4.2, “处理副本意外停机”。
当您备份副本的数据或传输其数据的快照以创建新副本时,请确保包括包含复制元数据存储库的mysql.slave_master_info和mysql.slave_relay_log_info表。对于克隆操作,请注意,当复制元数据存储库被创建为表时,在克隆操作期间会将其复制到接收方,但当它们被创建为文件时,则不会被复制。当使用基于二进制日志文件位置的复制时,需要复制元数据存储库以在重新启动已恢复、复制或克隆的副本后恢复复制。如果您没有中继日志文件,但仍然有应用程序元数据存储库,则可以检查它以确定复制 SQL 线程在源二进制日志中执行到哪个程度。然后,您可以使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)与SOURCE_LOG_FILE | MASTER_LOG_FILE和SOURCE_LOG_POS | MASTER_LOG_POS选项告诉副本从该点重新读取源的二进制日志(前提是所需的二进制日志仍然存在于源)。
另外创建了一个附加的存储库,即应用程序工作程序元数据存储库,主要用于内部使用,并保存有关多线程复制品上工作线程的状态信息。应用程序工作程序元数据存储库包括每个工作线程的中继日志文件和源二进制日志文件的名称和位置。如果将应用程序元数据存储库创建为表(这是默认设置),则将应用程序工作程序元数据存储库写入mysql.slave_worker_info表中。如果将应用程序元数据存储库写入文件,则将应用程序工作程序元数据存储库写入worker-relay-log.info文件中。对于外部使用,工作线程的状态信息显示在性能模式replication_applier_status_by_worker中。
复制元数据存储库最初包含类似于SHOW REPLICA STATUS语句输出中显示的信息,该语句在第 15.4.2 节“用于控制复制服务器的 SQL 语句”中讨论。此后,复制元数据存储库中添加了更多信息,这些信息不会被SHOW REPLICA STATUS语句显示。
对于连接元数据存储库,以下表显示了mysql.slave_master_info表中的列与SHOW REPLICA STATUS显示的列以及已弃用的master.info文件中的行之间的对应关系。
slave_master_info 表列SHOW REPLICA STATUS 列master.info 文件行描述Number_of_lines[无]1表中的列数(或文件中的行数)Master_log_nameSource_Log_File2当前正在从源读取的二进制日志的名称Master_log_posRead_Source_Log_Pos3已从源读取的二进制日志中的当前位置HostSource_Host4复制源服务器的主机名User_nameSource_User5用于连接到源的复制用户帐户名称User_password密码(SHOW REPLICA STATUS不显示)6用于连接到源的复制用户帐户密码PortSource_Port7用于连接到复制源服务器的网络端口Connect_retryConnect_Retry8复制品在尝试重新连接到源之前等待的时间段(以秒为单位)Enabled_sslSource_SSL_Allowed9复制端是否支持 SSL 连接Ssl_caSource_SSL_CA_File10用于证书颁发机构(CA)证书的文件Ssl_capathSource_SSL_CA_Path11证书颁发机构(CA)证书的路径Ssl_certSource_SSL_Cert12SSL 证书文件的名称Ssl_cipherSource_SSL_Cipher13SSL 连接握手中可能使用的密码列表Ssl_keySource_SSL_Key14SSL 密钥文件的名称Ssl_verify_server_certSource_SSL_Verify_Server_Cert15是否验证服务器证书Heartbeat[无]16复制心跳之间的间隔时间,单位为秒BindSource_Bind17连接源端时应使用的复制端网络接口Ignored_server_idsReplicate_Ignore_Server_Ids18要忽略的服务器 ID 列表。请注意,对于Ignored_server_ids,服务器 ID 列表前面会有要忽略的服务器 ID 总数。UuidSource_UUID19源端的唯一 IDRetry_countSource_Retry_Count20允许的最大重连尝试次数Ssl_crl[无]21SSL 证书吊销列表文件的路径Ssl_crlpath[无]22包含 SSL 证书吊销列表文件的目录路径Enabled_auto_positionAuto_position23是否使用 GTID 自动定位Channel_nameChannel_name24复制通道的名称Tls_versionSource_TLS_Version25源端的 TLS 版本Public_key_pathSource_public_key_path26RSA 公钥文件的名称Get_public_keyGet_source_public_key27是否从源端请求 RSA 公钥Network_namespaceNetwork_namespace28网络命名空间Master_compression_algorithm[无]29与源端连接的允许压缩算法Master_zstd_compression_level[无]30zstd压缩级别Tls_ciphersuites[无]31TLSv1.3 允许的密码套件Source_connection_auto_failover[无]32是否激活异步连接故障转移机制Gtid_only[无]33通道是否仅使用 GTID 并且不保留位置slave_master_info 表列SHOW REPLICA STATUS 列master.info 文件行描述
对于应用程序元数据存储库,以下表格显示了mysql.slave_relay_log_info表中的列与SHOW REPLICA STATUS显示的列以及已弃用的relay-log.info文件中的行之间的对应关系。
slave_relay_log_info 表列SHOW REPLICA STATUS 列relay-log.info 文件行描述Number_of_lines[无]1表中的列数或文件中的行数Relay_log_name中继日志文件2当前中继日志文件的名称Relay_log_posRelay_Log_Pos3中继日志文件中的当前位置;到达此位置的事件已在副本数据库上执行Master_log_name源二进制日志文件4从中继日志文件中读取事件的源二进制日志文件的名称Master_log_posExec_Source_Log_Pos5在副本上已执行的事件在源二进制日志文件中的相应位置Sql_delaySQL_Delay6副本必须滞后源的秒数Number_of_workers[无]7并行应用复制事务的工作线程数Id[无]8用于内部目的的 ID;目前始终为 1Channel_name通道名称9复制通道的名称Privilege_checks_username[无]10通道的PRIVILEGE_CHECKS_USER账户的用户名Privilege_checks_hostname[无]11通道的PRIVILEGE_CHECKS_USER账户的主机名Require_row_format[无]12通道是否仅接受基于行的事件Require_table_primary_key_check[无]13通道对于CREATE TABLE和ALTER TABLE操作是否要求表必须有主键的策略Assign_gtids_to_anonymous_transactions_type[无]14如果通道为尚未具有 GTID 的复制事务分配 GTID,使用副本的本地 UUID,则该值为LOCAL;如果通道使用手动设置的 UUID 进行分配,则该值为UUID。如果通道在这种情况下不分配 GTID,则该值为OFF。Assign_gtids_to_anonymous_transactions_value[无]15用于分配给匿名事务的 GTIDs 的 UUIDslave_relay_log_info 表列SHOW REPLICA STATUS 列relay-log.info 文件中的行描述
19.2.5 服务器如何评估复制过滤规则
原文:dev.mysql.com/doc/refman/8.0/en/replication-rules.html
19.2.5.1 数据库级复制和二进制日志选项的评估
19.2.5.2 表级复制选项的评估
19.2.5.3 复制过滤选项之间的交互
19.2.5.4 基于复制通道的过滤器
如果复制源服务器不将语句写入其二进制日志,则该语句不会被复制。如果服务器记录了该语句,则该语句将发送到所有复制端,每个复制端确定是否执行或忽略它。
在源端,您可以通过使用–binlog-do-db和–binlog-ignore-db选项来控制要记录更改的数据库。有关服务器在评估这些选项时使用的规则的描述,请参阅第 19.2.5.1 节,“数据库级复制和二进制日志选项的评估”。您不应该使用这些选项来控制要复制的数据库和表。相反,使用复制端的过滤器来控制在复制端执行的事件。
在复制端,关于是否执行或忽略从源端接收到的语句的决定是根据复制端启动时使用的–replicate-*选项进行的。(请参阅第 19.1.6 节,“复制和二进制日志选项和变量”。)这些选项管理的过滤器也可以使用CHANGE REPLICATION FILTER语句动态设置。管理这些过滤器的规则无论是在启动时使用–replicate-*选项创建还是在复制服务器运行时使用CHANGE REPLICATION FILTER创建,都是相同的。请注意,不能在配置为组复制的 MySQL 服务器实例上的组复制特定通道上使用复制过滤器,因为在某些服务器上过滤事务会使组无法达成一致状态。
在最简单的情况下,当没有–replicate-*选项时,复制端执行从源端接收到的所有语句。否则,结果取决于给定的特定选项。
数据库级选项(–replicate-do-db, –replicate-ignore-db)首先进行检查;请参阅 Section 19.2.5.1, “数据库级复制和二进制日志选项的评估”,了解此过程的描述。如果没有使用数据库级选项,则选项检查将继续到可能正在使用的任何表级选项(参见 Section 19.2.5.2, “表级复制选项的评估”,讨论这些选项)。如果使用了一个或多个数据库级选项但没有匹配的选项,则该语句不会被复制。
对仅影响数据库的语句(即,CREATE DATABASE, DROP DATABASE, 和 ALTER DATABASE),数据库级选项始终优先于任何–replicate-wild-do-table选项。换句话说,对于这样的语句,只有在没有适用的数据库级选项时才会检查–replicate-wild-do-table选项。
为了更容易确定给定选项集的影响,建议避免混合使用do-*和ignore-*选项,或包含通配符的选项与不包含通配符的选项混合使用。
如果指定了任何–replicate-rewrite-db选项,则它们会在测试–replicate-*过滤规则之前应用。
注意
所有复制过滤选项遵循与 MySQL 服务器中其他地方的数据库和表名称相同的大小写敏感规则,包括lower_case_table_names系统变量的影响。
从 MySQL 8.0.31 开始,在执行任何权限检查之前会应用过滤规则;如果事务被过滤掉,则不会为该事务执行任何权限检查,因此不会引发任何错误。更多信息请参阅 Section 19.5.1.29, “复制期间的复制错误”。
原文:dev.mysql.com/doc/refman/8.0/en/replication-rules-db-options.html
19.2.5.1 数据库级复制和二进制日志选项的评估
在评估复制选项时,复制开始时首先检查是否有适用的–replicate-do-db或–replicate-ignore-db选项。当使用–binlog-do-db或–binlog-ignore-db时,该过程类似,但选项在源上进行检查。
被检查是否匹配的数据库取决于正在处理的语句的二进制日志格式。如果使用行格式记录了该语句,则被更改数据的数据库是被检查的数据库。如果使用语句格式记录了该语句,则默认数据库(使用USE语句指定)是被检查的数据库。
注意
只有使用行格式的 DML 语句才能被记录。DDL 语句始终作为语句记录,即使binlog_format=ROW。因此,所有 DDL 语句都根据基于语句的复制规则进行过滤。这意味着你必须使用USE语句显式选择默认数据库,以便应用 DDL 语句。
对于复制,所涉及的步骤如下:
使用了哪种日志格式?
语句。 测试默认数据库。
行。 测试受更改影响的数据库。
是否有任何–replicate-do-db选项?
是。 数据库是否与它们中的任何一个匹配?
是。 继续到第 4 步。
否。 忽略更新并退出。
否。 继续到第 3 步。
是否有任何–replicate-ignore-db选项?
是。 数据库是否与它们中的任何一个匹配?
是。 忽略更新并退出。
否。 继续到第 4 步。
否。 继续到第 4 步。
如果有的话,继续检查表级复制选项。有关如何检查这些选项的描述,请参见Section 19.2.5.2, “Evaluation of Table-Level Replication Options”。
重要
在这个阶段仍然允许的语句实际上尚未执行。直到所有表级选项(如果有)也被检查,并且该过程的结果允许执行该语句为止,该语句才会被执行。
对于二进制日志记录,所涉及的步骤如下:
是否有–binlog-do-db或–binlog-ignore-db选项?
是的。 继续到第 2 步。
否。 记录该语句并退出。
是否存在默认数据库(是否已通过USE选择了任何数据库)?
是的。 继续到第 3 步。
否。 忽略该语句并退出。
存在默认数据库。是否有–binlog-do-db选项?
是的。 有任何匹配的数据库吗?
是的。 记录该语句并退出。
否。 忽略该语句并退出。
否。 继续到第 4 步。
任何–binlog-ignore-db选项是否与数据库匹配?
是的。 忽略该语句并退出。
否。 记录该语句并退出。
重要提示
对于基于语句的日志记录,在刚才给出的规则中对CREATE DATABASE、ALTER DATABASE和DROP DATABASE语句做了例外。在这些情况下,正在创建、更改或删除的数据库将替换默认数据库,以确定是否记录或忽略更新。
–binlog-do-db有时可能意味着“忽略其他数据库”。例如,当使用基于语句的日志记录时,仅使用–binlog-do-db=sales的服务器不会将与默认数据库不同的sales的语句写入二进制日志。当使用相同选项的基于行的日志记录时,服务器仅记录更改sales中数据的更新。
原文:dev.mysql.com/doc/refman/8.0/en/replication-rules-table-options.html
19.2.5.2 表级复制选项的评估
仅当以下两个条件之一为真时,副本才会检查和评估表选项:
未找到匹配的数据库选项。
找到了一个或多个数据库选项,并根据前一节中描述的规则评估这些选项,以确定“执行”条件。
首先,作为初步条件,副本检查是否启用了基于语句的复制。如果是,并且语句出现在存储函数中,则副本执行该语句并退出。如果启用了基于行的复制,则副本不知道语句是否出现在源上的存储函数中,因此此条件不适用。
注意
对于基于语句的复制,复制事件代表语句(构成给定事件的所有更改与单个 SQL 语句相关联);对于基于行的复制,每个事件代表单个表行的更改(因此,单个语句如UPDATE mytable SET mycol = 1可能会产生许多基于行的事件)。从事件的角度来看,检查表选项的过程对于基于行和基于语句的复制都是相同的。
到达这一点后,如果没有表选项,副本简单地执行所有事件。如果有任何–replicate-do-table或–replicate-wild-do-table选项,则事件必须与其中之一匹配才能执行;否则,它将被忽略。如果有任何–replicate-ignore-table或–replicate-wild-ignore-table选项,则执行所有事件,除了与这些选项之一匹配的事件。
重要
表级复制过滤器仅适用于在查询中明确提及并操作的表。它们不适用于查询隐式更新的表。例如,一个GRANT语句,更新mysql.user系统表但未提及该表,不受指定mysql.%作为通配符模式的过滤器影响。
以下步骤更详细地描述了此评估。 起点是数据库级选项评估的结束,如第 19.2.5.1 节,“数据库级复制和二进制日志选项的评估”中所述。
是否有任何表复制选项?
是的。 继续到第 2 步。
没有。 执行更新并退出。
使用哪种日志格式?
语句。 对执行更新的每个语句执行剩余步骤。
行。 对每个表行更新执行剩余步骤。
是否有任何–replicate-do-table选项?
是的。 表是否与其中任何表匹配?
是的。 执行更新并退出。
没有。 继续到第 4 步。
没有。 继续到第 4 步。
是否有任何–replicate-ignore-table选项?
是的。 表是否与其中任何表匹配?
是的。 忽略更新并退出。
没有。 继续到第 5 步。
没有。 继续到第 5 步。
是否有任何–replicate-wild-do-table选项?
是的。 表是否与其中任何表匹配?
是的。 执行更新并退出。
没有。 继续到第 6 步。
没有。 继续到第 6 步。
是否有任何–replicate-wild-ignore-table选项?
是的。 表是否与其中任何表匹配?
是的。 忽略更新并退出。
没有。 继续到第 7 步。
没有。 继续到第 7 步。
是否有另一个表需要测试?
是的。 返回到第 3 步。
没有。 继续到第 8 步。
是否有任何–replicate-do-table或–replicate-wild-do-table选项?
是的。 忽略更新并退出。
没有。 执行更新并退出。
注意
如果单个 SQL 语句同时操作一个被–replicate-do-table或–replicate-wild-do-table选项包含的表和另一个被–replicate-ignore-table或–replicate-wild-ignore-table选项忽略的表,基于语句的复制会停止。复制实例必须执行或忽略完整的语句(形成一个复制事件),逻辑上无法做到这一点。对于 DDL 语句的基于行的复制也适用这一规则,因为 DDL 语句始终被记录为语句,而不考虑生效的日志格式。唯一能够成功复制同时更新包含和被忽略表的语句类型是已使用binlog_format=ROW记录的 DML 语句。
原文:dev.mysql.com/doc/refman/8.0/en/replication-rules-examples.html
19.2.5.3 复制过滤选项之间的交互
如果您同时使用数据库级和表级复制过滤选项,副本首先根据数据库选项接受或忽略事件,然后根据表选项评估所有这些选项允许的事件。这有时可能导致看起来反直觉的结果。还要注意,结果会根据操作是使用基于语句还是基于行的二进制日志格式而变化。如果您希望确保您的复制过滤器始终以相同的方式运行,独立于二进制日志格式,这在使用混合二进制日志格式时尤为重要,请遵循本主题中的指导。
复制过滤选项的效果在不同的二进制日志格式之间有所不同,这是因为数据库名称的识别方式不同。在基于语句的格式中,DML 语句是基于当前数据库处理的,由USE语句指定。在基于行的格式中,DML 语句是基于修改表所在的数据库处理的。DDL 语句始终基于当前数据库进行过滤,由USE语句指定,而不受二进制日志格式的影响。
涉及多个表的操作也可能会因二进制日志格式的不同而受到复制过滤选项的影响。需要注意的操作包括涉及多表UPDATE语句的事务、触发器、级联外键、更新多个表的存储函数以及调用更新一个或多个表的存储函数的 DML 语句。如果这些操作同时更新被过滤进和被过滤出的表,结果可能会随着二进制日志格式的不同而变化。
如果您需要确保您的复制过滤器在不同的二进制日志格式下都能一致地运行,特别是如果您正在使用混合二进制日志格式(binlog_format=MIXED),请仅使用表级复制过滤选项,不要使用数据库级复制过滤选项。此外,不要使用同时更新被过滤进和被过滤出表的多表 DML 语句。
如果您需要同时使用数据库级和表级复制过滤器,并希望它们尽可能一致地运行,请选择以下策略之一:
如果您使用基于行的二进制日志格式(binlog_format=ROW),对于 DDL 语句,依赖USE语句设置数据库,不要指定数据库名称。您可以考虑更改为基于行的二进制日志格式以提高与复制过滤的一致性。有关更改二进制日志格式适用的条件,请参见 Section 7.4.4.2, “Setting The Binary Log Format”。
如果您使用基于语句或混合二进制日志格式(binlog_format=STATEMENT或MIXED),对于 DML 和 DDL 语句,依赖USE语句,不要使用数据库名称。此外,不要使用同时更新过滤进和过滤出表的多表 DML 语句。
示例 19.7 一个–replicate-ignore-db选项和一个–replicate-do-table选项
在复制源服务器上,发出以下语句:
USE db1;
CREATE TABLE t2 LIKE t1;
INSERT INTO db2.t3 VALUES (1);
副本设置了以下复制过滤选项:
replicate-ignore-db = db1
replicate-do-table = db2.t3
DDL 语句CREATE TABLE在db1中创建表,如前述USE语句指定。副本根据其–replicate-ignore-db = db1选项过滤掉此语句,因为db1是当前数据库。无论复制源服务器上的二进制日志格式如何,结果都是相同的。然而,DML INSERT语句的结果取决于二进制日志格式:
如果源服务器上使用基于行的二进制日志格式(binlog_format=ROW),副本使用表存在的数据库db2评估INSERT操作。首先评估数据库级选项–replicate-ignore-db = db1,因此不适用。表级选项–replicate-do-table = db2.t3适用,因此副本将更改应用于表t3。
如果源端使用基于语句的二进制日志格式(binlog_format=STATEMENT),那么复制端将使用由USE语句设置为db1且未更改的默认数据库来评估INSERT操作。根据其数据库级别的–replicate-ignore-db = db1选项,因此它会忽略该操作,不会将更改应用于表t3。表级别的选项–replicate-do-table = db2.t3不会被检查,因为该语句已经匹配了一个数据库级别的选项并被忽略。
如果在复制端需要–replicate-ignore-db = db1选项,并且在源端使用基于语句(或混合)的二进制日志格式也是必要的,可以通过在INSERT语句中省略数据库名称并依赖于USE语句来使结果保持一致,如下所示:
USE db1;
CREATE TABLE t2 LIKE t1;
USE db2;
INSERT INTO t3 VALUES (1);
在这种情况下,复制端始终基于数据库db2评估INSERT语句。无论操作是以语句为基础还是以行为基础的二进制格式记录,结果都是一样的。
原文:dev.mysql.com/doc/refman/8.0/en/replication-rules-channel-based-filters.html
19.2.5.4 复制通道基于过滤器
本节解释了在存在多个复制通道时如何使用复制过滤器,例如在多源复制拓扑中。在 MySQL 8.0 之前,所有复制过滤器都是全局的,因此过滤器适用于所有复制通道。从 MySQL 8.0 开始,复制过滤器可以是全局的或特定于通道的,使您能够在特定复制通道上配置具有复制过滤器的多源副本。特定于通道的复制过滤器在多源复制拓扑中特别有用,当相同数据库或表存在于多个源上时,并且只需要从一个源复制副本时。
有关设置复制通道的说明,请参见第 19.1.5 节,“MySQL 多源复制”,有关其工作原理的更多信息,请参见第 19.2.2 节,“复制通道”。
重要
多源副本上的每个通道必须从不同源复制。即使您使用复制过滤器在每个通道上选择不同的数据进行复制,也不能从单个副本到单个源设置多个复制通道。这是因为副本的服务器 ID 在复制拓扑中必须是唯一的。源仅通过副本的服务器 ID 来区分副本,而不是通过复制通道的名称,因此它无法识别来自同一副本的不同复制通道。
重要
在配置为组复制的 MySQL 服务器实例上,可以在与组复制无直接关系的复制通道上使用特定于通道的复制过滤器,例如,其中一个组成员还充当来自组外部源的副本。它们不能用于group_replication_applier或group_replication_recovery通道。在这些通道上进行过滤会使组无法达成一致状态的协议。
重要
对于钻石拓扑结构中的多源复制(其中复制品从两个或更多源复制,这些源源自一个共同的源),当使用基于 GTID 的复制时,请确保多源复制的所有通道上的任何复制过滤器或其他通道配置都是相同的。使用基于 GTID 的复制时,过滤器仅应用于事务数据,而 GTID 不会被过滤掉。这样做是为了使复制品的 GTID 集与源的保持一致,这意味着可以使用 GTID 自动定位而无需每次重新获取被过滤掉的事务。在下游复制品是多源的情况下,并且在钻石拓扑结构中从多个源接收相同事务的情况下,下游复制品现在具有事务的多个版本,结果取决于哪个通道首先应用该事务。尝试的第二个通道使用 GTID 自动跳过跳过事务,因为事务的 GTID 已被第一个通道添加到gtid_executed集中。在通道上具有相同过滤器的情况下,没有问题,因为所有事务的版本都包含相同的数据,因此结果是相同的。然而,如果通道上的过滤器不同,数据库可能变得不一致,复制可能会停滞。
复制过滤器和通道概述
当存在多个复制通道时,例如在多源复制拓扑中,复制过滤器应用如下:
任何指定的全局复制过滤器都会添加到过滤器类型(do_db、do_ignore_table等)的全局复制过滤器中。
任何特定于通道的复制过滤器都会将过滤器添加到指定通道的指定过滤器类型的复制过滤器中。
如果未配置此类型的通道特定复制过滤器,则每个复制通道将全局复制过滤器复制到其特定于通道的复制过滤器中。
每个通道使用其特定于通道的复制过滤器来过滤复制流。
创建频道特定复制过滤器的语法扩展了现有的 SQL 语句和命令选项。当未指定复制频道时,全局复制过滤器被配置以确保向后兼容性。CHANGE REPLICATION FILTER语句支持FOR CHANNEL子句在线配置频道特定过滤器。使用–replicate-*命令选项配置过滤器可以指定复制频道,形式为–replicate-*filter_type*=*channel_name*:*filter_details*。假设在服务器启动之前存在channel_1和channel_2频道;在这种情况下,使用命令行选项–replicate-do-db=db1 –replicate-do-db=channel_1:db2 –replicate-do-db=db3 –replicate-ignore-db=db4 –replicate-ignore-db=channel_2:db5 –replicate-wild-do-table=channel_1:db6.t1% 将导致:
全局复制过滤器: do_db=db1,db3; ignore_db=db4
channel_1 上的频道特定过滤器: do_db=db2; ignore_db=db4; wild-do-table=db6.t1%
channel_2 上的频道特定过滤器: do_db=db1,db3; ignore_db=db5
在复制品的my.cnf文件中包含时,这些相同规则可以在启动时应用,如下所示:
replicate-do-db=db1
replicate-do-db=channel_1:db2
replicate-ignore-db=db4
replicate-ignore-db=channel_2:db5
replicate-wild-do-table=db6.channel_1.t1%
在这种设置中监视复制过滤器,请使用replication_applier_global_filters和replication_applier_filters表。
在启动时配置频道特定复制过滤器
与复制过滤器相关的命令选项可以在可选的*channel*后跟一个冒号,然后是过滤器规范。第一个冒号被解释为分隔符,后续的冒号被解释为字面冒号。以下命令选项支持使用此格式配置频道特定复制过滤器:
–replicate-do-db=*channel*:*database_id*
–replicate-ignore-db=*channel*:*database_id*
–replicate-do-table=*channel*:*table_id*
–replicate-ignore-table=*channel*:*table_id*
–replicate-rewrite-db=*channel*:*db1-db2*
–replicate-wild-do-table=*channel*:*table* *pattern*
–replicate-wild-ignore-table=*channel*:*table* *pattern*
所有列出的选项都可以在副本的my.cnf文件中使用,与大多数其他 MySQL 服务器启动选项一样,省略前两个破折号。参见 Overview of Replication Filters and Channels,以及 Section 6.2.2.2, “Using Option Files”中的简短示例。
如果使用冒号但不为过滤选项指定*channel,例如–replicate-do-db=:*database_id*,则该选项将为默认复制通道配置复制过滤器。默认复制通道是一旦启动复制就始终存在的复制通道,与手动创建的多源复制通道不同。当既不指定冒号也不指定channel*时,该选项将配置全局复制过滤器,例如–replicate-do-db=*database_id*配置全局–replicate-do-db过滤器。
如果配置了多个rewrite-db=*from_name*->*to_name*选项与相同的*from_name*数据库,所有过滤器将被添加在一起(放入rewrite_do列表中),第一个生效。
用于–replicate-wild-*-table选项的*pattern*可以包括标识符中允许的任何字符,以及通配符%和_。这些与LIKE操作符一起使用时的工作方式相同;例如,tbl%匹配任何以tbl开头的表名,而tbl_匹配与tbl匹配的表名加一个额外字符。
在线更改通道特定的复制过滤器
除了–replicate-*选项外,还可以使用CHANGE REPLICATION FILTER语句配置复制过滤器。这样可以避免重新启动服务器,但在进行更改时必须停止复制 SQL 线程。要使此语句将过滤器应用于特定通道,请使用FOR CHANNEL *channel*子句。例如:
CHANGE REPLICATION FILTER REPLICATE_DO_DB=(db1) FOR CHANNEL channel_1;
当提供FOR CHANNEL子句时,语句将作用于指定通道的复制过滤器。如果指定了多种类型的过滤器(do_db、do_ignore_table、wild_do_table等),则只有指定的过滤器类型会被语句替换。例如,在具有多个通道的复制拓扑结构中,例如在多源复制中,如果没有提供FOR CHANNEL子句,则语句将作用于全局复制过滤器和所有通道的复制过滤器,使用与FOR CHANNEL情况类似的逻辑。更多信息请参见 Section 15.4.2.2, “CHANGE REPLICATION FILTER Statement”。
移除通道特定的复制过滤器
当配置了通道特定的复制过滤器时,可以通过发出空的过滤器类型语句来移除过滤器。例如,要从名为channel_1的复制通道中移除所有REPLICATE_REWRITE_DB过滤器,请发出:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB=() FOR CHANNEL channel_1;
之前使用命令选项或CHANGE REPLICATION FILTER配置的任何REPLICATE_REWRITE_DB过滤器都会被移除。
RESET REPLICA ALL 语句会移除在被语句删除的通道上设置的通道特定的复制过滤器。当被删除的通道重新创建时,任何为副本指定的全局复制过滤器会被复制到它们,而不会应用任何通道特定的复制过滤器。
19.3 复制安全性
原文:dev.mysql.com/doc/refman/8.0/en/replication-security.html
19.3.1 设置复制使用加密连接
19.3.2 加密二进制日志文件和中继日志文件
19.3.3 复制权限检查
为防止未经授权访问存储在复制源服务器和副本之间传输的数据,设置所有涉及的服务器使用您在安装中为任何 MySQL 实例选择的安全措施,如第八章,“安全”中所述。此外,对于复制拓扑中的服务器,考虑实施以下安全措施:
设置源和副本使用加密连接传输二进制日志,以保护这些数据在传输中。必须使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句激活这些连接的加密,另外还需设置服务器支持加密网络连接。参见第 19.3.1 节,“设置复制使用加密连接”。
在源和副本上加密二进制日志文件和中继日志文件,以保护这些数据在静态状态下,以及在二进制日志缓存中使用的任何数据。二进制日志加密通过binlog_encryption系统变量激活。参见第 19.3.2 节,“加密二进制日志文件和中继日志文件”。
将权限检查应用于复制应用程序,有助于保护复制通道免受未经授权或意外使用特权或不需要的操作。权限检查通过设置一个PRIVILEGE_CHECKS_USER账户来实现,MySQL 用它来验证您是否已为该通道的每个特定事务授权。参见第 19.3.3 节,“复制权限检查”。
对于组复制,可以使用二进制日志加密和权限检查作为复制组成员的安全措施。您还应考虑加密组成员之间的连接,包括组通信连接和分布式恢复连接,并应用 IP 地址白名单以排除不受信任的主机。有关组复制特定安全措施的信息,请参见第 20.6 节,“组复制安全”。
19.3.1 设置复制使用加密连接
原文:dev.mysql.com/doc/refman/8.0/en/replication-encrypted-connections.html
要在复制过程中使用加密连接传输二进制日志,源服务器和副本服务器都必须支持加密网络连接。如果任一服务器不支持加密连接(因为它未被编译或配置为支持),则无法通过加密连接进行复制。
为了为复制设置加密连接,与为客户端/服务器连接设置类似。您必须获取(或创建)一个适当的安全证书,可以在源端使用,并在每个副本上使用来自同一证书颁发机构的类似证书。您还必须获取适当的密钥文件。
有关设置服务器和客户端使用加密连接的更多信息,请参见第 8.3.1 节,“配置 MySQL 使用加密连接”。
要在源端启用加密连接,您必须创建或获取适当的证书和密钥文件,然后将以下配置参数添加到源端 my.cnf 文件的 [mysqld] 部分中,根据需要更改文件名:
[mysqld]
ssl_ca=cacert.pem
ssl_cert=server-cert.pem
ssl_key=server-key.pem
文件的路径可以是相对的或绝对的;我们建议您始终为此目的使用完整路径。
配置参数如下:
ssl_ca:证书颁发机构(CA)证书文件的路径名。(ssl_capath类似,但指定了 CA 证书文件的目录路径名。)
ssl_cert:服务器公钥证书文件的路径名。此证书可以发送给客户端,并根据其拥有的 CA 证书进行验证。
ssl_key:服务器私钥文件的路径名。
要在副本端启用加密连接,使用 CHANGE REPLICATION SOURCE TO 语句(MySQL 8.0.23 及更高版本)或 CHANGE MASTER TO 语句(MySQL 8.0.23 之前)。
要使用 CHANGE REPLICATION SOURCE TO(CHANGE MASTER TO)命名副本的证书和 SSL 私钥文件,添加适当的 SOURCE_SSL_*xxx*(MASTER_SSL_*xxx*)选项,如下所示:
-> SOURCE_SSL_CA = \’ca_file_name\’,
-> SOURCE_SSL_CAPATH = \’ca_directory_name\’,
-> SOURCE_SSL_CERT = \’cert_file_name\’,
-> SOURCE_SSL_KEY = \’key_file_name\’,
这些选项对应于相同名称的–ssl-*xxx*选项,如加密连接的命令选项中所述。要使这些选项生效,还必须设置SOURCE_SSL=1。对于复制连接,为SOURCE_SSL_CA或SOURCE_SSL_CAPATH中的任一值指定一个值相当于设置–ssl-mode=VERIFY_CA。只有在使用指定信息找到有效匹配的证书颁发机构(CA)证书时,连接尝试才会成功。
要激活主机名身份验证,添加SOURCE_SSL_VERIFY_SERVER_CERT选项,如下所示:
-> SOURCE_SSL_VERIFY_SERVER_CERT=1,
此选项对应于–ssl-verify-server-cert选项,在 MySQL 5.7 中已弃用,并在 MySQL 8.0 中删除。对于复制连接,指定MASTER_SSL_VERIFY_SERVER_CERT=1相当于设置–ssl-mode=VERIFY_IDENTITY,如加密连接的命令选项中所述。要使此选项生效,还必须设置SOURCE_SSL=1。主机名身份验证无法与自签名证书一起使用。
要激活证书吊销列表(CRL)检查,添加SOURCE_SSL_CRL或SOURCE_SSL_CRLPATH选项,如下所示:
-> SOURCE_SSL_CRL = \’crl_file_name\’,
-> SOURCE_SSL_CRLPATH = \’crl_directory_name\’,
这些选项对应于相同名称的–ssl-*xxx*选项,如加密连接的命令选项中所述。如果未指定,将不进行 CRL 检查。
要指定副本允许的密码、密码套件和加密协议列表,使用SOURCE_SSL_CIPHER、SOURCE_TLS_VERSION和SOURCE_TLS_CIPHERSUITES选项,如下所示:
-> SOURCE_SSL_CIPHER = \’cipher_list\’,
-> SOURCE_TLS_VERSION = \’protocol_list\’,
-> SOURCE_TLS_CIPHERSUITES = \’ciphersuite_list\’,
SOURCE_SSL_CIPHER选项指定了一个由冒号分隔的一个或多个副本允许的密码。
SOURCE_TLS_VERSION选项指定了一个由逗号分隔的 TLS 加密协议列表,副本允许用于复制连接,格式类似于tls_version服务器系统变量。连接过程协商使用源和副本都允许的最高 TLS 版本。为了能够连接,副本必须至少与源有一个 TLS 版本相同。
SOURCE_TLS_CIPHERSUITES选项(从 MySQL 8.0.19 开始提供)指定了一个以冒号分隔的允许副本使用的一个或多个密码套件列表,如果连接使用 TLSv1.3。如果在使用 TLSv1.3 时将此选项设置为NULL(如果您没有设置该选项,则默认为此),则允许启用默认启用的密码套件。如果将选项设置为空字符串,则不允许任何密码套件,并且因此不使用 TLSv1.3。
您可以在这些列表中指定的协议、密码和密码套件取决于用于编译 MySQL 的 SSL 库。有关格式、允许的值以及如果不指定选项时的默认值的信息,请参阅第 8.3.2 节,“加密连接 TLS 协议和密码”。
注意
在 MySQL 8.0.16 到 8.0.18 中,MySQL 支持 TLSv1.3,但SOURCE_TLS_CIPHERSUITES选项不可用。在这些版本中,如果源和副本之间的连接使用 TLSv1.3,则源必须允许至少一个默认启用的 TLSv1.3 密码套件的使用。从 MySQL 8.0.19 开始,您可以使用该选项指定任何密码套件的选择,包括仅非默认密码套件(如果需要)。
更新源信息后,在副本上启动复制过程,如下所示:
mysql> START SLAVE;
从 MySQL 8.0.22 开始,首选使用START REPLICA,如下所示:
mysql> START REPLICA;
你可以使用SHOW REPLICA STATUS(在 MySQL 8.0.22 之前,SHOW SLAVE STATUS)语句来确认已成功建立加密连接。
在副本上要求加密连接并不意味着源要求来自副本的加密连接。如果要确保源仅接受使用加密连接连接的副本,可以在源上创建一个使用REQUIRE SSL选项的复制用户帐户,然后授予该用户REPLICATION SLAVE权限。例如:
mysql> CREATE USER \’repl\’@\’%.example.com\’ IDENTIFIED BY \’*password*\’
-> REQUIRE SSL;
mysql> GRANT REPLICATION SLAVE ON *.*
-> TO \’repl\’@\’%.example.com\’;
如果您在源上有现有的复制用户帐户,可以使用以下语句向其添加REQUIRE SSL:
mysql> ALTER USER \’repl\’@\’%.example.com\’ REQUIRE SSL;
19.3.2 加密二进制日志文件和中继日志文件
原文:dev.mysql.com/doc/refman/8.0/en/replication-binlog-encryption.html
19.3.2.1 二进制日志加密范围
19.3.2.2 二进制日志加密密钥
19.3.2.3 二进制日志主密钥轮换
从 MySQL 8.0.14 开始,二进制日志文件和中继日志文件可以进行加密,有助于保护这些文件以及其中可能包含的敏感数据,防止外部攻击者滥用,也防止操作系统用户未经授权查看。文件使用的加密算法是 AES(高级加密标准)密码算法,内置于 MySQL Server 中,无法配置。
通过将 MySQL 服务器上的 binlog_encryption 系统变量设置为 ON 来启用此加密。OFF 是默认值。该系统变量为二进制日志文件和中继日志文件设置加密。要启用加密,服务器上不需要启用二进制日志记录,因此可以在没有二进制日志的副本上加密中继日志文件。要使用加密,必须安装和配置一个密钥环组件或插件以提供 MySQL Server 的密钥环服务。有关如何执行此操作的说明,请参见 Section 8.4.4, “The MySQL Keyring”。任何支持的密钥环组件或插件都可以用于存储二进制日志加密密钥。
当首次启用加密时,服务器会在初始化二进制日志和中继日志之前生成一个新的二进制日志加密密钥。该密钥用于为每个二进制日志文件(如果服务器启用了二进制日志记录)和中继日志文件(如果服务器有复制通道)加密文件密码,并从文件密码生成的进一步密钥用于加密文件中的数据。服务器当前正在使用的二进制日志加密密钥称为二进制日志主密钥。两层加密密钥架构意味着可以根据需要轮换(用新的主密钥替换)二进制日志主密钥,只需重新使用新主密钥重新加密每个文件的文件密码,而不是整个文件。中继日志文件对所有通道进行加密,包括在激活加密后创建的新通道。二进制日志索引文件和中继日志索引文件永远不会被加密。
如果在服务器运行时激活加密,则会生成一个新的二进制日志加密密钥。例外情况是,如果之前在服务器上激活了加密,然后禁用了加密,那么之前使用的二进制日志加密密钥将再次被使用。二进制日志文件和中继日志文件立即轮换,新文件和所有后续的二进制日志文件和中继日志文件的文件密码都使用此二进制日志加密密钥进行加密。服务器上仍存在的现有二进制日志文件和中继日志文件不会被加密,但如果不再需要,可以清除它们。
如果通过将binlog_encryption 系统变量更改为 OFF 来停用加密,则二进制日志文件和中继日志文件将立即轮换,并且所有后续记录都将是未加密的。先前加密的文件不会自动解密,但服务器仍然能够读取它们。在服务器运行时激活或停用加密需要BINLOG_ENCRYPTION_ADMIN 权限。
可以通过加密日志文件头部的魔数来区分加密和未加密的二进制日志文件(加密日志文件为0xFD62696E,而未加密日志文件为0xFE62696E)。SHOW BINARY LOGS 语句显示每个二进制日志文件是加密还是未加密。
当二进制日志文件被加密时,mysqlbinlog 无法直接读取,但可以使用–read-from-remote-server选项从服务器读取。从 MySQL 8.0.14 开始,mysqlbinlog 如果尝试直接读取加密的二进制日志文件,将返回适当的错误,但旧版本的mysqlbinlog 根本不会将文件识别为二进制日志文件。如果使用mysqlbinlog 备份加密的二进制日志文件,请注意,使用mysqlbinlog 生成的文件副本以未加密格式存储。
二进制日志加密可以与二进制日志事务压缩结合使用(自 MySQL 8.0.20 起可用)。有关二进制日志事务压缩的更多信息,请参见 Section 7.4.4.5, “Binary Log Transaction Compression”。
原文:dev.mysql.com/doc/refman/8.0/en/replication-binlog-encryption-scope.html
19.3.2.1 二进制日志加密范围
当 MySQL 服务器实例启用二进制日志加密时,加密覆盖范围如下:
写入二进制日志文件和中继日志文件的静态数据从加密开始的时间点起,使用上述两层加密架构进行加密。在启动加密时存在于服务器上的现有二进制日志文件和中继日志文件不会被加密。当这些文件不再需要时,可以清除这些文件。
在发送到 MySQL 客户端(包括mysqlbinlog)的复制事件流中的数据在传输时会被解密,因此应通过使用连接加密(参见第 8.3 节,“使用加密连接”和第 19.3.1 节,“设置复制使用加密连接”)来保护传输中的数据。
在事务期间存储在二进制日志事务和语句缓存中的数据以未加密格式存在于存储缓存的内存缓冲区中。如果超过内存缓冲区可用空间,数据将写入磁盘上的临时文件。从 MySQL 8.0.17 开始,当服务器上启用二进制日志加密时,用于保存二进制日志缓存的临时文件将使用 AES-CTR(AES Counter mode)进行流加密进行加密。由于临时文件是易失性的并且与单个进程绑定,因此它们使用单层加密进行加密,使用仅存在于内存中且永远不会存储在磁盘或密钥环中的随机生成的文件密码和初始化向量。在每个事务提交后,二进制日志缓存被重置:内存缓冲区被清除,用于保存二进制日志缓存的任何临时文件被截断,并为下一个事务使用随机生成的新文件密码和初始化向量。在服务器正常关闭或意外停止后重新启动时,也会进行此重置。
注意
如果在设置binlog_format=STATEMENT时使用LOAD DATA,这不被推荐,因为该语句被认为对基于语句的复制不安全,将在应用更改的副本上创建包含数据的临时文件。当服务器上启用二进制日志加密时,这些临时文件不会被加密。相反,请改用基于行或混合二进制日志格式,这些格式不会创建临时文件。
原文:dev.mysql.com/doc/refman/8.0/en/replication-binlog-encryption-encryption-keys.html
19.3.2.2 二进制日志加密密钥
用于加密日志文件的文件密码的二进制日志加密密钥是为每个 MySQL 服务器实例专门生成的 256 位密钥,使用 MySQL 服务器的密钥环服务生成(参见第 8.4.4 节,“MySQL 密钥环”)。密钥环服务处理二进制日志加密密钥的创建、检索和删除。服务器实例仅为自身创建和删除生成的密钥,但如果存储在密钥环中,则可以读取为其他实例生成的密钥,例如通过文件复制克隆的服务器实例的情况。
重要提示
MySQL 服务器实例的二进制日志加密密钥必须包含在您的备份和恢复程序中,因为如果丢失了解密当前和保留的二进制日志文件或中继日志文件的文件密码所需的密钥,可能无法启动服务器。
密钥环中二进制日志加密密钥的格式如下:
MySQLReplicationKey_{UUID}_{SEQ_NO}
例如:
MySQLReplicationKey_00508583-b5ce-11e8-a6a5-0010e0734796_1
{UUID} 是由 MySQL 服务器生成的真实 UUID(server_uuid 系统变量的值)。{SEQ_NO} 是二进制日志加密密钥的序列号,对于在服务器上生成的每个新密钥,该序列号递增 1。
目前在服务器上使用的二进制日志加密密钥称为二进制日志主密钥。当前二进制日志主密钥的序列号存储在密钥环中。二进制日志主密钥用于加密每个新日志文件的文件密码,这是一个特定于用于加密文件数据的日志文件的随机生成的 32 字节文件密码。文件密码使用 AES-CBC(AES 密码块链接模式)使用 256 位二进制日志加密密钥和随机初始化向量(IV)进行加密,并存储在日志文件的文件头中。文件数据使用从文件密码生成的 256 位密钥和从文件密码生成的随机数也生成的随机数使用 AES-CTR(AES 计数器模式)进行加密。如果知道用于加密文件密码的二进制日志加密密钥,则可以使用 OpenSSL 密码工具包中提供的工具离线解密加密文件。
如果您使用文件复制来克隆一个具有加密功能的 MySQL 服务器实例,使其二进制日志文件和中继日志文件被加密,请确保也复制了密钥环,以便克隆服务器可以从源服务器读取二进制日志加密密钥。当在克隆服务器上激活加密(无论是在启动时还是随后),克隆服务器会意识到与复制文件一起使用的二进制日志加密密钥包括源服务器的生成的 UUID。它会自动生成一个新的二进制日志加密密钥,使用自己生成的 UUID,并将其用于加密后续的二进制日志文件和中继日志文件的文件密码。复制的文件将继续使用源服务器的密钥进行读取。
原文:dev.mysql.com/doc/refman/8.0/en/replication-binlog-encryption-key-rotation.html
19.3.2.3 二进制日志主密钥旋转
当启用二进制日志加密时,您可以在服务器运行时随时通过执行ALTER INSTANCE ROTATE BINLOG MASTER KEY来旋转二进制日志主密钥。当使用此语句手动旋转二进制日志主密钥时,新文件和随后的文件的密码将使用新的二进制日志主密钥加密,同时现有加密的二进制日志文件和中继日志文件的文件密码将使用新的二进制日志主密钥重新加密,因此加密完全更新。您可以定期旋转二进制日志主密钥以符合组织的安全策略,如果怀疑当前或任何以前的二进制日志主密钥可能已被泄露,也可以这样做。
当您手动旋转二进制日志主密钥时,MySQL 服务器按顺序执行以下操作:
生成一个具有下一个可用序列号的新二进制日志加密密钥,存储在密钥环中,并用作新的二进制日志主密钥。
所有通道上的二进制日志和中继日志文件都会被旋转。
新的二进制日志主密钥用于加密新的二进制日志和中继日志文件的文件密码,以及直到再次更改密钥为止的随后文件。
服务器上现有加密的二进制日志文件和中继日志文件的文件密码将依次使用新的二进制日志主密钥重新加密,从最近的文件开始。任何未加密的文件将被跳过。
在重新加密过程后不再用于任何文件的二进制日志加密密钥将从密钥环中删除。
需要BINLOG_ENCRYPTION_ADMIN权限才能执行ALTER INSTANCE ROTATE BINLOG MASTER KEY,如果binlog_encryption系统变量设置为OFF,则无法使用该语句。
作为二进制日志主密钥轮换过程的最后一步,清理掉不再适用于任何保留的二进制日志文件或中继日志文件的所有二进制日志加密密钥。如果无法为保留的二进制日志文件或中继日志文件初始化重新加密,那么相关的二进制日志加密密钥不会被删除,以防将来可以恢复文件。例如,如果二进制日志索引文件中列出的文件当前无法读取,或者通道无法初始化,可能会出现这种情况。如果服务器 UUID 更改,例如因为使用 MySQL Enterprise Backup 创建的备份用于设置新的副本,那么在新服务器上发出ALTER INSTANCE ROTATE BINLOG MASTER KEY不会删除包括原始服务器 UUID 的任何早期二进制日志加密密钥。
如果二进制日志主密钥轮换过程的前四个步骤中有任何一个无法正确完成,系统会发出错误消息,解释情况以及对二进制日志文件和中继日志文件的加密状态的影响。先前加密的文件始终保持在加密状态,但它们的文件密码可能仍然使用旧的二进制日志主密钥进行加密。如果您看到这些错误,请首先通过再次发出ALTER INSTANCE ROTATE BINLOG MASTER KEY来重试该过程。然后调查各个文件的状态,看看是什么阻碍了该过程,特别是如果您怀疑当前或任何以前的二进制日志主密钥可能已被泄露。
如果二进制日志主密钥轮换过程的最后一步无法正确完成,系统会发出警告消息,解释情况。警告消息会指出该过程无法清理用于轮换二进制日志主密钥的辅助密钥,或无法清理未使用的二进制日志加密密钥。您可以选择忽略该消息,因为这些密钥是辅助密钥或不再使用,或者您可以再次发出ALTER INSTANCE ROTATE BINLOG MASTER KEY来重试该过程。
如果服务器在二进制日志主密钥轮换过程中停止并重新启动,而二进制日志加密仍然设置为ON,则重新启动后的新二进制日志文件和中继日志文件将使用新的二进制日志主密钥进行加密。但是,现有文件的重新加密不会继续进行,因此在服务器停止之前未重新加密的文件将继续使用先前的二进制日志主密钥进行加密。要完成重新加密并清理未使用的二进制日志加密密钥,请在重新启动后再次发出ALTER INSTANCE ROTATE BINLOG MASTER KEY。
ALTER INSTANCE ROTATE BINLOG MASTER KEY 操作不会被写入二进制日志,也不会在副本上执行。因此,在包含多个 MySQL 版本的复制环境中可以执行二进制日志主密钥轮换。要在所有适用的源和副本服务器上定期轮换二进制日志主密钥,您可以在每个服务器上启用 MySQL 事件调度程序,并使用 CREATE EVENT 语句发出 ALTER INSTANCE ROTATE BINLOG MASTER KEY 语句。如果因为怀疑当前或任何以前的二进制日志主密钥可能已被泄露而轮换二进制日志主密钥,则在每个适用的源和副本服务器上发出该语句。在各个服务器上发出该语句可确保您可以验证即时的合规性,即使在滞后的副本、属于多个复制拓扑或当前未在复制拓扑中活动但具有二进制日志和中继日志文件的情况下也是如此。
binlog_rotate_encryption_master_key_at_startup 系统变量控制服务器在重新启动时是否自动轮换二进制日志主密钥。如果此系统变量设置为 ON,则在服务器重新启动时会生成一个新的二进制日志加密密钥,并将其用作新的二进制日志主密钥。如果设置为 OFF,即默认值,则在重新启动后再次使用现有的二进制日志主密钥。当在启动时轮换二进制日志主密钥时,新的二进制日志和中继日志文件的文件密码将使用新密钥加密。现有加密的二进制日志文件和中继日志文件的文件密码不会重新加密,因此它们仍然使用旧密钥加密,该旧密钥仍然可在密钥环中使用。
19.3.3 复制权限检查
原文:dev.mysql.com/doc/refman/8.0/en/replication-privilege-checks.html
19.3.3.1 用于复制 PRIVILEGE_CHECKS_USER 帐户的权限
19.3.3.2 Group Replication Channels 的权限检查
19.3.3.3 从失败的复制权限检查中恢复
默认情况下,MySQL 复制(包括 Group Replication)在将已被另一台服务器接受的事务应用于副本或组成员时不执行权限检查。从 MySQL 8.0.18 开始,您可以创建一个具有适当权限的用户帐户来应用通常在通道上复制的事务,并将其指定为复制应用程序的 PRIVILEGE_CHECKS_USER 帐户,使用 CHANGE REPLICATION SOURCE TO 语句(从 MySQL 8.0.23 开始)或 CHANGE MASTER TO 语句(在 MySQL 8.0.23 之前)。然后,MySQL 检查每个事务是否符合用户帐户的权限,以验证您已授权该通道的操作。该帐户还可以安全地由管理员使用,以应用或重新应用来自 mysqlbinlog 输出的事务,例如从通道上的复制错误中恢复。
使用 PRIVILEGE_CHECKS_USER 帐户有助于保护复制通道免受未经授权或意外使用特权或不需要的操作。在以下情况下,PRIVILEGE_CHECKS_USER 帐户提供了额外的安全层:
您正在在组织网络上的服务器实例和另一个网络上的服务器实例之间进行复制,例如云服务提供商提供的实例。
您希望将多个本地部署或外部部署作为单独的单元进行管理,而不是给予一个管理员帐户对所有部署的权限。
您希望拥有一个管理员帐户,使管理员仅能执行与复制通道和其复制的数据库直接相关的操作,而不是在服务器实例上拥有广泛的权限。
当您为通道指定 PRIVILEGE_CHECKS_USER 帐户时,您可以通过在 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 语句中添加以下选项之一或两者来增加应用权限检查的复制通道的安全性:
REQUIRE_ROW_FORMAT选项(从 MySQL 8.0.19 开始提供)使复制通道仅接受基于行的复制事件。当设置REQUIRE_ROW_FORMAT时,您必须在源服务器上使用基于行的二进制日志记录(binlog_format=ROW)。在 MySQL 8.0.18 中,REQUIRE_ROW_FORMAT不可用,但仍强烈建议在受保护的复制通道中使用基于行的二进制日志记录。使用基于语句的二进制日志记录时,可能需要一些管理员级别的特权才能使PRIVILEGE_CHECKS_USER账户成功执行事务。
REQUIRE_TABLE_PRIMARY_KEY_CHECK选项(从 MySQL 8.0.20 开始提供)使复制通道使用自己的主键检查策略。设置为ON表示始终需要主键,设置为OFF表示永远不需要主键。默认设置为STREAM,使用从源复制的每个事务的值设置sql_require_primary_key系统变量的会话值。当设置PRIVILEGE_CHECKS_USER时,将REQUIRE_TABLE_PRIMARY_KEY_CHECK设置为ON或OFF意味着用户帐户无需会话管理级别特权来设置受限制的会话变量,这些变量是更改sql_require_primary_key值所需的。它还规范化了不同源的复制通道的行为。
您授予REPLICATION_APPLIER权限以使用户账户能够出现为复制应用程序线程的PRIVILEGE_CHECKS_USER,并执行 mysqlbinlog 使用的内部BINLOG语句。PRIVILEGE_CHECKS_USER账户的用户名和主机名必须遵循第 8.2.4 节,“指定帐户名称”中描述的语法,并且用户不能是匿名用户(具有空白用户名)或CURRENT_USER。要创建新帐户,请使用CREATE USER语句。要授予此帐户REPLICATION_APPLIER权限,请使用GRANT语句。例如,要创建一个名为priv_repl的用户帐户,该帐户可以由example.com域中的任何主机的管理员手动使用,并且需要加密连接,请执行以下语句:
mysql> SET sql_log_bin = 0;
mysql> CREATE USER \’priv_repl\’@\’%.example.com\’ IDENTIFIED BY \’*password*\’ REQUIRE SSL;
mysql> GRANT REPLICATION_APPLIER ON *.* TO \’priv_repl\’@\’%.example.com\’;
mysql> SET sql_log_bin = 1;
SET sql_log_bin语句用于使账户管理语句不会被添加到二进制日志中并发送到复制通道(参见第 15.4.1.3 节,“SET sql_log_bin 语句”)。
重要提示
caching_sha2_password身份验证插件是从 MySQL 8.0 开始新创建用户的默认插件(有关详细信息,请参见 Section 8.4.1.2, “Caching SHA-2 Pluggable Authentication”)。要使用使用此插件进行身份验证的用户帐户连接到服务器,您必须设置加密连接,如 Section 19.3.1, “Setting Up Replication to Use Encrypted Connections”中所述,或启用不加密连接以支持使用 RSA 密钥对进行密码交换。
设置用户帐户后,使用GRANT语句授予附加权限,以使用户帐户能够执行您期望应用程序线程执行的数据库更改,例如更新服务器上保存的特定表。这些相同的权限使管理员能够在需要手动执行任何这些事务的情况下使用该帐户在复制通道上执行操作。如果尝试执行未授予适当权限的意外操作,则该操作将被拒绝,并且复制应用程序线程将停止并显示错误。Section 19.3.3.1, “Privileges For The Replication PRIVILEGE_CHECKS_USER Account”解释了帐户需要的其他权限。例如,要授予priv_repl用户帐户向db1中的cust表添加行的INSERT权限,发出以下语句:
mysql> GRANT INSERT ON db1.cust TO \’priv_repl\’@\’%.example.com\’;
通过CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(MySQL 8.0.23 之前)为复制通道分配PRIVILEGE_CHECKS_USER帐户。如果复制正在运行,请在CHANGE MASTER TO语句之前发出STOP REPLICA(或在 MySQL 8.0.22 之前,STOP SLAVE)命令,并在其后发出START REPLICA。强烈建议在设置PRIVILEGE_CHECKS_USER时使用基于行的二进制日志记录,并且从 MySQL 8.0.19 开始,您可以使用该语句设置REQUIRE_ROW_FORMAT以强制执行此操作。
当重新启动复制通道时,动态特权的检查从那时开始应用。但是,静态全局特权在应用程序的上下文中不活动,直到重新加载授权表,因为这些特权不会更改为连接的客户端。要激活静态特权,请执行刷新特权操作。可以通过发出FLUSH PRIVILEGES语句或执行mysqladmin flush-privileges或mysqladmin reload命令来完成此操作。
例如,在运行中的 MySQL 8.0.23 及更高版本中,要在通道channel_1上启动特权检查,请执行以下语句:
mysql> STOP REPLICA FOR CHANNEL \’channel_1\’;
mysql> CHANGE REPLICATION SOURCE TO
> PRIVILEGE_CHECKS_USER = \’priv_repl\’@\’%.example.com\’,
> REQUIRE_ROW_FORMAT = 1 FOR CHANNEL \’channel_1\’;
mysql> FLUSH PRIVILEGES;
mysql> START REPLICA FOR CHANNEL \’channel_1\’;
在 MySQL 8.0.23 之前,您可以使用以下显示的语句:
mysql> STOP SLAVE FOR CHANNEL \’channel_1\’;
mysql> CHANGE MASTER TO
> PRIVILEGE_CHECKS_USER = \’priv_repl\’@\’%.example.com\’,
> REQUIRE_ROW_FORMAT = 1 FOR CHANNEL \’channel_1\’;
mysql> FLUSH PRIVILEGES;
mysql> START SLAVE FOR CHANNEL \’channel_1\’;
如果未指定通道且不存在其他通道,则该语句将应用于默认通道。在性能模式replication_applier_configuration表中显示了频道的PRIVILEGE_CHECKS_USER帐户的用户名和主机名,它们已经适当转义,因此可以直接复制到 SQL 语句中以执行单个事务。
在 MySQL 8.0.31 及更高版本中,如果使用Rewriter插件,则应授予PRIVILEGE_CHECKS_USER用户帐户SKIP_QUERY_REWRITE特权。这可以防止此用户发出的语句被重写。有关更多信息,请参见第 7.6.4 节,“Rewriter Query Rewrite Plugin”。
当为复制通道设置REQUIRE_ROW_FORMAT时,复制应用程序不会创建或删除临时表,因此不会设置pseudo_thread_id会话系统变量。它不执行LOAD DATA INFILE指令,因此不会尝试文件操作以访问或删除与数据加载相关的临时文件(作为Format_description_log_event记录)。它不执行INTVAR、RAND和USER_VAR事件,这些事件用于重现基于语句的复制的客户端连接状态。 (一个例外是与 DDL 查询相关的USER_VAR事件,这些事件将被执行。)它不执行在 DML 事务中记录的任何语句。如果复制应用程序在尝试排队或应用事务时检测到这些类型的事件之一,则不会应用该事件,并且复制将因错误而停止。
无论是否设置了PRIVILEGE_CHECKS_USER账户,都可以为复制通道设置REQUIRE_ROW_FORMAT。即使没有特权检查,当设置此选项时实施的限制也会增加复制通道的安全性。在使用mysqlbinlog时,还可以指定–require-row-format选项,以强制在mysqlbinlog输出中执行基于行的复制事件。
安全上下文。 默认情况下,当使用指定的用户账户启动复制应用程序线程作为PRIVILEGE_CHECKS_USER时,安全上下文将使用默认角色创建,或者如果activate_all_roles_on_login设置为ON,则使用所有角色。
你可以使用角色为作为PRIVILEGE_CHECKS_USER账户使用的账户提供一般的权限集,就像以下示例中所示。在这里,与之前的示例中直接向用户账户授予db1.cust表的INSERT权限不同,这个权限被授予给了角色priv_repl_role,同时还有REPLICATION_APPLIER权限。然后使用该角色将权限集授予两个用户账户,这两个账户现在都可以作为PRIVILEGE_CHECKS_USER账户使用:
mysql> SET sql_log_bin = 0;
mysql> CREATE USER \’priv_repa\’@\’%.example.com\’
IDENTIFIED BY \’*password*\’
REQUIRE SSL;
mysql> CREATE USER \’priv_repb\’@\’%.example.com\’
IDENTIFIED BY \’*password*\’
REQUIRE SSL;
mysql> CREATE ROLE \’priv_repl_role\’;
mysql> GRANT REPLICATION_APPLIER TO \’priv_repl_role\’;
mysql> GRANT INSERT ON db1.cust TO \’priv_repl_role\’;
mysql> GRANT \’priv_repl_role\’ TO
\’priv_repa\’@\’%.example.com\’,
\’priv_repb\’@\’%.example.com\’;
mysql> SET DEFAULT ROLE \’priv_repl_role\’ TO
\’priv_repa\’@\’%.example.com\’,
\’priv_repb\’@\’%.example.com\’;
mysql> SET sql_log_bin = 1;
请注意,当复制应用程序线程创建安全上下文时,它会检查PRIVILEGE_CHECKS_USER账户的权限,但不执行密码验证,并且不执行与账户管理相关的检查,例如检查账户是否被锁定。创建的安全上下文在复制应用程序线程的生命周期内保持不变。
限制。 在 MySQL 8.0.18 版本中,如果在发出RESET REPLICA语句后立即重新启动复制mysqld(由于意外服务器退出或有意重启),则mysql.slave_relay_log_info表中保存的PRIVILEGE_CHECKS_USER账户设置将丢失,必须重新指定。在使用特权检查时,始终在重新启动后验证它们是否存在,并在需要时重新指定。从 MySQL 8.0.19 开始,在这种情况下,PRIVILEGE_CHECKS_USER账户设置将被保留,因此它将从表中检索并重新应用到通道中。
原文:dev.mysql.com/doc/refman/8.0/en/replication-privilege-checks-account.html
19.3.3.1 用于复制 PRIVILEGE_CHECKS_USER 账户的特权
使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句指定的用户账户作为复制通道的PRIVILEGE_CHECKS_USER账户必须具有REPLICATION_APPLIER特权,否则复制应用程序线程将无法启动。如第 19.3.3 节“复制特权检查”所述,该账户需要进一步的特权,足以应用在复制通道上预期的所有预期事务。这些特权仅在执行相关事务时才会检查。
强烈建议对使用PRIVILEGE_CHECKS_USER账户保护的复制通道使用基于行的二进制日志记录(binlog_format=ROW)。对于基于语句的二进制日志记录,PRIVILEGE_CHECKS_USER账户可能需要一些管理员级别的特权才能成功执行事务。从 MySQL 8.0.19 开始,可以将REQUIRE_ROW_FORMAT设置应用于受保护的通道,限制通道执行需要这些特权的事件。
REPLICATION_APPLIER特权明确或隐含允许PRIVILEGE_CHECKS_USER账户执行复制线程需要执行的以下操作:
设置系统变量gtid_next,original_commit_timestamp,original_server_version,immediate_server_version,以及pseudo_replica_mode或pseudo_slave_mode的值,以在执行事务时应用适当的元数据和行为。
执行内部使用的BINLOG语句来应用mysqlbinlog输出,前提是该账户还具有这些语句中的表和操作的权限。
更新系统表 mysql.gtid_executed、mysql.slave_relay_log_info、mysql.slave_worker_info 和 mysql.slave_master_info,以更新复制元数据。(如果事件明确访问这些表以进行其他目的,必须在这些表上授予适当的权限。)
应用二进制日志 Table_map_log_event,提供表元数据但不进行任何数据库更改。
如果 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 语句的 REQUIRE_TABLE_PRIMARY_KEY_CHECK 选项设置为默认的 STREAM,PRIVILEGE_CHECKS_USER 账户需要具有足够权限设置受限制的会话变量,以便它可以在会话期间更改与源复制的设置匹配的 sql_require_primary_key 系统变量的值。SESSION_VARIABLES_ADMIN 权限赋予该账户此功能。此权限还允许账户应用使用使用 –disable-log-bin 选项创建的 mysqlbinlog 输出。如果将 REQUIRE_TABLE_PRIMARY_KEY_CHECK 设置为 ON 或 OFF,则副本始终在复制操作中使用该值作为 sql_require_primary_key 系统变量的值,因此不需要这些会话管理级别的权限。
如果使用表加密,table_encryption_privilege_check 系统变量设置为 ON,并且涉及任何事件的表空间的加密设置与应用服务器的默认加密设置(由 default_table_encryption 系统变量指定)不同,PRIVILEGE_CHECKS_USER 账户需要具有 TABLE_ENCRYPTION_ADMIN 权限才能覆盖默认加密设置。强烈建议不要授予此权限。相反,确保副本上的默认加密设置与其复制的表空间的加密状态匹配,并且复制组成员具有相同的默认加密设置,这样就不需要该权限。
为了从中继日志执行特定的复制事务,或根据需要执行来自 mysqlbinlog 输出的事务,PRIVILEGE_CHECKS_USER 账户必须具有以下权限:
对于以行格式记录的行插入(记录为Write_rows_log_event),需要在相关表上具有INSERT权限。
对于以行格式记录的行更新(记录为Update_rows_log_event),需要在相关表上具有UPDATE权限。
对于以行格式记录的行删除(记录为Delete_rows_log_event),需要在相关表上具有DELETE权限。
如果正在使用基于语句的二进制日志记录(不建议在PRIVILEGE_CHECKS_USER账户下使用),对于像BEGIN或COMMIT或以语句格式记录的 DML(记录为Query_log_event)的事务控制语句,PRIVILEGE_CHECKS_USER账户需要有执行事件中包含的语句所需的权限。
如果需要在复制通道上执行LOAD DATA操作,请使用基于行的二进制日志记录(binlog_format=ROW)。使用此日志记录格式时,不需要FILE权限来执行事件,因此不要给PRIVILEGE_CHECKS_USER账户此权限。强烈建议在使用PRIVILEGE_CHECKS_USER账户保护的复制通道上使用基于行的二进制日志记录。如果为通道设置了REQUIRE_ROW_FORMAT,则需要基于行的二进制日志记录。处理LOAD DATA事件创建的任何临时文件的Format_description_log_event会在不进行权限检查的情况下进行。有关更多信息,请参见 Section 19.5.1.19, “Replication and LOAD DATA”。
如果init_replica或init_slave系统变量被设置为指定在复制 SQL 线程启动时要执行的一个或多个 SQL 语句,则PRIVILEGE_CHECKS_USER账户必须具有执行这些语句所需的权限。
不建议将任何 ACL 权限授予PRIVILEGE_CHECKS_USER账户,包括CREATE USER,CREATE ROLE,DROP ROLE和GRANT OPTION,也不允许该账户更新mysql.user表。拥有这些权限,该账户可以用于在服务器上创建或修改用户账户。为避免源服务器上发出的 ACL 语句被复制到安全通道以供执行(在缺少这些权限的情况下会失败),您可以在所有 ACL 语句之前发出SET sql_log_bin = 0,在其后发出SET sql_log_bin = 1,以从源二进制日志中省略这些语句。或者,您可以在执行所有 ACL 语句之前设置一个专用的当前数据库,并使用复制过滤器(–binlog-ignore-db)来在副本中过滤掉这个数据库。
原文:dev.mysql.com/doc/refman/8.0/en/replication-privilege-checks-gr.html
19.3.3.2 组复制通道的权限检查
从 MySQL 8.0.19 开始,除了保护异步和半同步复制外,您还可以选择使用PRIVILEGE_CHECKS_USER帐户来保护组复制使用的两个复制应用程序线程。每个组成员上的group_replication_applier线程用于应用组的事务,每个组成员上的group_replication_recovery线程用于从二进制日志中进行状态传输,作为成员加入或重新加入组时的分布式恢复的一部分。
要保护其中一个线程,停止组复制,然后使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)并指定PRIVILEGE_CHECKS_USER选项,将group_replication_applier或group_replication_recovery作为通道名称。例如:
mysql> STOP GROUP_REPLICATION;
mysql> CHANGE MASTER TO PRIVILEGE_CHECKS_USER = \’gr_repl\’@\’%.example.com\’
FOR CHANNEL \’group_replication_recovery\’;
mysql> FLUSH PRIVILEGES;
mysql> START GROUP_REPLICATION;
Or from MySQL 8.0.23:
mysql> STOP GROUP_REPLICATION;
mysql> CHANGE REPLICATION SOURCE TO PRIVILEGE_CHECKS_USER = \’gr_repl\’@\’%.example.com\’
FOR CHANNEL \’group_replication_recovery\’;
mysql> FLUSH PRIVILEGES;
mysql> START GROUP_REPLICATION;
对于组复制通道,当通道创建时会自动启用REQUIRE_ROW_FORMAT设置,无法禁用,因此您无需指定此设置。
重要提示
在 MySQL 8.0.19 中,请确保在运行组复制时不要使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句与PRIVILEGE_CHECKS_USER选项。此操作会导致通道的中继日志文件被清除,可能导致已接收并排队在中继日志中但尚未应用的事务丢失。
Group Replication 要求每个要被组复制的表都必须有一个定义的主键,或者等效的主键,其中等效的主键是一个非空唯一键。与sql_require_primary_key系统变量执行的检查不同,Group Replication 有自己内置的一套用于主键或主键等效的检查。您可以为 Group Replication 通道设置CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的REQUIRE_TABLE_PRIMARY_KEY_CHECK选项为ON。但是,请注意,您可能会发现一些在 Group Replication 内置检查下允许的事务,在设置sql_require_primary_key = ON或REQUIRE_TABLE_PRIMARY_KEY_CHECK = ON时不被允许。因此,从 MySQL 8.0.20(引入该选项时)开始,新的和升级的 Group Replication 通道将REQUIRE_TABLE_PRIMARY_KEY_CHECK设置为默认的STREAM,而不是ON。
如果在 Group Replication 中使用远程克隆操作进行分布式恢复(参见 Section 20.5.4.2, “Cloning for Distributed Recovery”),从 MySQL 8.0.19 开始,PRIVILEGE_CHECKS_USER账户和相关设置从捐赠方克隆到加入成员。如果设置加入成员在启动时启动 Group Replication,则它会自动使用该账户对适当的复制通道进行特权检查。
在 MySQL 8.0.18 中,由于一些限制,建议不要在 Group Replication 通道中使用PRIVILEGE_CHECKS_USER账户。
原文:dev.mysql.com/doc/refman/8.0/en/replication-privilege-checks-recover.html
19.3.3.3 从失败的复制特权检查中恢复
如果针对PRIVILEGE_CHECKS_USER账户的特权检查失败,则不会执行事务,并且通道上的复制将停止。错误的详细信息和最后应用的事务记录在性能模式replication_applier_status_by_worker表中。按照以下步骤从错误中恢复:
确定导致错误的复制事件,并验证事件是否预期且来自可信任的来源。您可以使用mysqlbinlog检索和显示围绕错误发生时间记录的事件。有关如何执行此操作的说明,请参见第 9.5 节,“时间点(增量)恢复” Recovery\”)。
如果复制的事件是意外的或不是来自已知和可信任的来源,请调查原因。如果您能够确定事件发生的原因,并且没有安全考虑因素,请按照以下描述修复错误。
如果PRIVILEGE_CHECKS_USER账户应该被允许执行事务,但已经配置错误,请向账户授予缺失的特权,使用FLUSH PRIVILEGES语句或执行mysqladmin flush-privileges或mysqladmin reload命令重新加载授权表,然后重新启动通道上的复制。
如果需要执行事务并且已经验证了其可信性,但PRIVILEGE_CHECKS_USER账户通常不应具有此特权,您可以临时授予PRIVILEGE_CHECKS_USER账户所需的特权。在应用了复制事件之后,从账户中删除特权,并采取任何必要的步骤确保事件不会再次发生(如果可以避免)。
如果事务是应该仅在源端而不是在副本上发生的管理操作,或者应该仅在单个复制组成员上发生,可以在停止复制的服务器上跳过事务,然后发出START REPLICA来重新启动通道上的复制。为了避免将来出现这种情况,您可以在这些管理语句之前使用SET sql_log_bin = 0,之后再使用SET sql_log_bin = 1,这样它们就不会在源端记录。
如果事务是一个不应该在源端或副本端发生的 DDL 或 DML 语句,请在停止复制的服务器上跳过该事务,然后在原始发生事务的服务器上手动撤销该事务,最后发出START REPLICA以重新启动复制。
要跳过一个事务,如果正在使用 GTIDs,请提交一个具有失败事务 GTID 的空事务,例如:
SET GTID_NEXT=\’aaa-bbb-ccc-ddd:N\’;
BEGIN;
COMMIT;
SET GTID_NEXT=\’AUTOMATIC\’;
如果没有使用 GTIDs,请发出SET GLOBAL sql_replica_skip_counter或SET GLOBAL sql_slave_skip_counter语句以跳过该事件。有关使用此替代方法和有关跳过事务的更多详细信息,请参见 Section 19.1.7.3, “Skipping Transactions”。
19.4 复制解决方案
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions.html
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.4.1 节,“用于备份的复制”。
关于在源和副本上使用不同存储引擎的建议和提示,请参见第 19.4.4 节,“使用不同源和副本存储引擎进行复制”。
将复制用作扩展解决方案需要对使用该解决方案的应用程序的逻辑和操作进行一些更改。请参见第 19.4.5 节,“用于扩展的复制”。
出于性能或数据分发原因,您可能希望将不同数据库复制到不同的副本。请参见第 19.4.6 节,“将不同数据库复制到不同副本”。
随着副本数量的增加,源的负载可能会增加,导致性能降低(因为需要将二进制日志复制到每个副本)。有关改善复制性能的提示,包括使用单个辅助服务器作为源,请参见第 19.4.7 节,“改善复制性能”。
关于切换数据源的指导,或将复制品转换为数据源作为紧急故障转移解决方案的一部分,请参阅第 19.4.8 节,“故障转移期间切换数据源”。
关于复制拓扑中服务器特定的安全措施信息,请参阅第 19.3 节,“复制安全性”。
19.4.1 使用复制进行备份
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-backups.html
19.4.1.1 使用 mysqldump 备份副本
19.4.1.2 从副本备份原始数据
19.4.1.3 通过将源或副本设置为只读状态备份
要将复制用作备份解决方案,请将数据从源复制到副本,然后备份副本。副本可以暂停和关闭而不影响源的运行操作,因此您可以生成“实时”数据的有效快照,否则需要关闭源才能完成。
如何备份数据库取决于其大小以及您是仅备份数据还是备份数据和副本状态,以便在发生故障时可以重建副本。因此有两种选择:
如果您使用复制作为解决方案来使您能够备份源上的数据,并且您的数据库大小不是太大,那么mysqldump工具可能适合。请参阅 Section 19.4.1.1, “使用 mysqldump 备份副本”。
对于较大的数据库,mysqldump可能不切实际或低效,您可以备份原始数据文件。使用原始数据文件选项还意味着您可以备份二进制和中继日志,以便在副本故障时重新创建副本。有关更多信息,请参阅 Section 19.4.1.2, “从副本备份原始数据”。
另一种备份策略,可用于源服务器或副本服务器,是将服务器设置为只读状态。备份针对只读服务器执行,然后将其更改回通常的读/写操作状态。请参阅 Section 19.4.1.3, “通过将源或副本设置为只读状态备份”。
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-backups-mysqldump.html
19.4.1.1 使用 mysqldump 备份副本
使用mysqldump创建数据库副本可以捕获数据库中的所有数据,并以一种格式导入到另一个 MySQL Server 实例中(参见第 6.5.4 节,“mysqldump — A Database Backup Program”)。由于信息的格式是 SQL 语句,因此文件可以轻松分发并应用于正在运行的服务器,以便在紧急情况下访问数据。但是,如果您的数据集很大,使用mysqldump可能不切实际。
提示
考虑使用 MySQL Shell 转储工具,提供多线程并行转储、文件压缩和进度信息显示,以及云功能,如 Oracle Cloud Infrastructure Object Storage 流式传输和 MySQL HeatWave Service 兼容性检查和修改。转储可以使用 MySQL Shell 加载转储工具轻松导入到 MySQL Server 实例或 MySQL HeatWave Service DB System 中。MySQL Shell 的安装说明可在此处找到。
使用mysqldump在开始转储过程之前应停止副本上的复制,以确保转储包含一致的数据集:
停止副本处理请求。您可以使用mysqladmin完全停止副本上的复制:
$> mysqladmin stop-slave
或者,您可以仅停止复制 SQL 线程以暂停事件执行:
$> mysql -e \’STOP SLAVE SQL_THREAD;\’
Or from MySQL 8.0.22:
$> mysql -e \’STOP REPLICA SQL_THREAD;\’
这使得副本可以继续接收来自源二进制日志的数据更改事件,并使用复制接收器线程将其存储在中继日志中,但阻止副本执行这些事件并更改其数据。在繁忙的复制环境中,允许复制接收器线程在备份期间运行可能会加快重新启动复制应用程序线程时的赶上过程。
运行 mysqldump 来转储您的数据库。您可以转储所有数据库或选择要转储的数据库。例如,要转储所有数据库:
$> mysqldump –all-databases > fulldb.dump
转储完成后,重新启动复制:
$> mysqladmin start-slave
在上面的示例中,您可能希望将登录凭据(用户名、密码)添加到命令中,并将整个过程打包成一个脚本,以便每天自动运行。
如果您采用这种方法,请确保监控复制过程,以确保运行备份所需的时间不会影响副本跟上源事件的能力。请参见第 19.1.7.1 节,“检查复制状态”。如果副本无法跟上,您可能需要添加另一个副本并分发备份过程。有关如何配置此场景的示例,请参见第 19.4.6 节,“将不同数据库复制到不同副本”。
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-backups-rawdata.html
19.4.1.2 从复制中备份原始数据
为了保证复制的文件完整性,在关闭 MySQL 复制服务器时备份原始数据文件应该进行。如果 MySQL 服务器仍在运行,后台任务可能仍在更新数据库文件,特别是涉及具有后台进程的存储引擎,如InnoDB。对于InnoDB,这些问题应该在崩溃恢复期间得到解决,但由于在备份过程中关闭复制服务器而不影响源执行的能力,可以利用这一功能。
要关闭服务器并备份文件:
关闭复制 MySQL 服务器:
$> mysqladmin shutdown
复制数据文件。您可以使用任何适当的复制或存档工具,包括cp,tar或WinZip。例如,假设数据目录位于当前目录下,您可以将整个目录存档如下:
$> tar cf /tmp/dbbackup.tar ./data
再次启动 MySQL 服务器。在 Unix 系统下:
$> mysqld_safe &
在 Windows 系统下:
C:\\> \”C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysqld\”
通常应该备份整个复制 MySQL 服务器的数据目录。如果您希望能够恢复数据并作为复制运行(例如,在复制发生故障时),除了数据外,您还需要复制的连接元数据存储库和应用程序元数据存储库,以及中继日志文件。这些项目在恢复复制数据后需要用于恢复复制。假设表已用于复制的连接元数据存储库和应用程序元数据存储库(请参阅 Section 19.2.4, “Relay Log and Replication Metadata Repositories”),这是 MySQL 8.0 的默认设置,这些表将与数据目录一起备份。如果文件已用于存储库,这已被弃用,您必须单独备份这些文件。如果中继日志文件已放置在与数据目录不同的位置,则必须单独备份中继日志文件。
如果您丢失了中继日志但仍有relay-log.info文件,您可以检查它以确定复制 SQL 线程在源二进制日志中执行到哪个程度。然后,您可以使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)与SOURCE_LOG_FILE | MASTER_LOG_FILE和SOURCE_LOG_POS | MASTER_LOG_POS选项告诉复制从那一点重新读取二进制日志。这要求源服务器上的二进制日志仍然存在。
如果您的复制品正在复制LOAD DATA语句,您还应该备份复制品用于此目的的目录中存在的任何SQL_LOAD-*文件。复制品需要这些文件来恢复任何中断的LOAD DATA操作的复制。此目录的位置是系统变量replica_load_tmpdir(从 MySQL 8.0.26 开始)或slave_load_tmpdir(在 MySQL 8.0.26 之前)。如果服务器未使用该变量启动,则目录位置是tmpdir系统变量的值。
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-backups-read-only.html
19.4.1.3 通过将其设置为只读来备份源或复制品
可以通过获取全局读锁并操作 read_only 系统变量来改变要备份服务器的只读状态,从而备份复制设置中的源或复制服务器:
将服务器设置为只读,以便仅处理检索并阻止更新。
执行备份。
将服务器改回正常的读写状态。
注意
本节中的说明将要备份的服务器置于安全状态,以便备份方法从服务器获取数据,例如 mysqldump(参见 第 6.5.4 节,“mysqldump — 数据库备份程序”)。您不应尝试使用这些说明通过直接复制文件来进行二进制备份,因为服务器可能仍然在内存中缓存修改的数据,尚未刷新到磁盘。
本节中的说明描述了如何为源和复制品执行此操作。对于这里讨论的两种场景,假设您有以下复制设置:
一个源服务器 S1
一个复制服务器 R1,其源为 S1
一个连接到 S1 的客户端 C1
一个连接到 R1 的客户端 C2
在任一场景中,获取全局读锁并操作 read_only 变量的语句是在要备份的服务器上执行的,不会传播到该服务器的任何副本。
场景 1:只读源备份
通过在源 S1 上执行以下语句,将源 S1 置于只读状态:
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SET GLOBAL read_only = ON;
当 S1 处于只读状态时,以下属性为真:
由 C1 发送到 S1 的更新请求被阻塞,因为服务器处于只读模式。
由 C1 发送到 S1 的查询结果请求成功。
在 S1 上进行备份是安全的。
在 R1 上进行备份是不安全的。该服务器仍在运行,并且可能正在处理二进制日志或来自客户端 C2 的更新请求。
当 S1 处于只读状态时,执行备份。例如,您可以使用 mysqldump。
在 S1 上的备份操作完成后,通过执行以下语句将 S1 恢复到正常运行状态:
mysql> SET GLOBAL read_only = OFF;
mysql> UNLOCK TABLES;
尽管在 S1 上执行备份是安全的(就备份而言),但对性能来说并不是最佳选择,因为 S1 的客户端被阻止执行更新操作。
这种策略适用于在复制设置中备份源,但也可以用于非复制设置中的单个服务器。
场景 2:只读复制备份
通过在复制 R1 上执行以下语句,将复制 R1 置于只读状态:
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SET GLOBAL read_only = ON;
当 R1 处于只读状态时,以下属性为真:
源 S1 仍在运行,因此在源上进行备份是不安全的。
副本 R1 已停止,因此在副本 R1 上进行备份是安全的。
这些属性为一种常见的备份场景提供了基础:让一个副本在一段时间内忙于执行备份不会造成问题,因为它不会影响整个网络,而且系统在备份期间仍在运行。特别是,客户端仍然可以在源服务器上执行更新操作,而备份副本上的备份活动不会对源服务器产生影响。
当 R1 处于只读状态时,执行备份操作。例如,您可以使用mysqldump。
完成 R1 上的备份操作后,通过执行以下语句将 R1 恢复到正常运行状态:
mysql> SET GLOBAL read_only = OFF;
mysql> UNLOCK TABLES;
将副本恢复到正常运行状态后,它会通过追赶源的二进制日志中的任何未完成更新再次与源进行同步。
19.4.2 处理复制品意外停止
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-unexpected-replica-halt.html
为了使复制对服务器的意外停止具有弹性(有时被描述为崩溃安全),必须使复制品能够在停止之前恢复其状态。本节描述了复制过程中复制品意外停止的影响,以及如何配置复制品以获得继续复制的最佳恢复机会。
在复制品意外停止后,重新启动时,复制 SQL 线程必须恢复已执行的事务的信息。恢复所需的信息存储在复制品的应用程序元数据存储库中。从 MySQL 8.0 开始,默认情况下,此存储库以名为mysql.slave_relay_log_info的InnoDB表的形式创建。通过使用这种事务性存储引擎,信息始终可以在重新启动时恢复。对应用程序元数据存储库的更新与事务一起提交,这意味着记录在该存储库中的复制品进度信息始终与已应用于数据库的内容一致,即使服务器意外停止也是如此。有关应用程序元数据存储库的更多信息,请参见第 19.2.4 节“中继日志和复制元数据存储库”。
DML 事务和原子 DDL 更新也会在mysql.slave_relay_log_info表中更新复制品的应用程序元数据存储库的复制位置,并将更改应用于数据库,作为一个原子操作。在所有其他情况下,包括不完全原子的 DDL 语句和不支持原子 DDL 的豁免存储引擎,如果服务器意外停止,mysql.slave_relay_log_info表可能会缺少与复制数据相关的更新。在这种情况下,恢复更新是一个手动过程。有关 MySQL 8.0 中原子 DDL 支持的详细信息以及某些语句复制的结果行为,请参见第 15.1.1 节“原子数据定义语句支持”。
复制品从意外停止中恢复的恢复过程取决于复制品的配置。恢复过程的细节受到复制方法的选择、复制品是单线程还是多线程以及相关系统变量设置的影响。恢复过程的总体目标是确定在意外停止发生之前复制品的数据库上已经应用了哪些事务,并检索并应用在意外停止后复制品错过的事务。
对于基于 GTID 的复制,恢复过程需要副本已经接收或提交的事务的 GTID。缺失的事务可以通过 GTID 自动定位从源获取,该过程会自动比较源的事务和副本的事务,并识别缺失的事务。
对于基于文件位置的复制,恢复过程需要准确的复制 SQL 线程(应用程序)位置,显示在副本上应用的最后一个事务。基于该位置,复制 I/O 线程(接收器)从源的二进制日志中检索应该从该点开始在副本上应用的所有事务。
使用基于 GTID 的复制使得配置复制以应对意外停止变得最容易。GTID 自动定位意味着副本可以可靠地识别和检索缺失的事务,即使应用事务序列中存在间隙。
以下信息提供了适用于不同类型副本的设置组合,以确保在复制控制范围内尽可能实现恢复。
重要提示
复制控制范围之外的一些因素可能会影响复制恢复过程和恢复过程后复制的整体状态。特别是,影响各个存储引擎恢复过程的设置可能导致在副本意外停止时丢失事务,因此这些事务对于复制恢复过程不可用。下面列表中提到的innodb_flush_log_at_trx_commit=1设置是使用带有事务的InnoDB的复制设置的关键设置。然而,特定于InnoDB或其他存储引擎的其他设置,特别是与刷新或同步相关的设置,也可能会产生影响。始终检查并应用您选择的存储引擎关于崩溃安全设置的建议。
在副本上的以下设置组合对于意外停止是最具弹性的:
当使用基于 GTID 的复制时(gtid_mode=ON),设置SOURCE_AUTO_POSITION=1 | MASTER_AUTO_POSITION=1,这将激活 GTID 自动定位,使连接到源的连接自动识别并检索丢失的事务。可以使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(MySQL 8.0.23 之前)来设置此选项。如果复制品有多个复制通道,则需要为每个通道单独设置此选项。有关 GTID 自动定位的工作原理的详细信息,请参见第 19.1.3.3 节,“GTID 自动定位”。当使用基于文件位置的复制时,不使用SOURCE_AUTO_POSITION=1 | MASTER_AUTO_POSITION=1,而是使用二进制日志位置或中继日志位置来控制复制开始的位置。
从 MySQL 8.0.27 开始,当使用基于 GTID 的复制时(gtid_mode=ON),设置GTID_ONLY=1,这使得复制品在恢复过程中仅使用 GTID,并停止在复制元数据存储库中持久化二进制日志和中继日志文件名和文件位置。可以使用CHANGE REPLICATION SOURCE TO语句来设置此选项。如果复制品有多个复制通道,则需要为每个通道单独设置此选项。使用GTID_ONLY=1时,在恢复过程中,将忽略文件位置信息,并使用 GTID 自动跳过来跳过已经提供的事务,而不是识别正确的文件位置。这种策略更有效,前提是您使用relay_log_purge的默认设置清除中继日志,这意味着只需要检查一个中继日志文件。
设置sync_relay_log=1,指示复制接收线程在每个接收的事务写入后将中继日志同步到磁盘。这意味着副本从源二进制日志中读取的当前位置记录(在应用程序元数据存储库中)永远不会超过保存在中继日志中的事务记录。请注意,尽管这个设置是最安全的,但由于涉及磁盘写入的次数较多,因此也是最慢的。当sync_relay_log > 1或sync_relay_log=0(其中同步由操作系统处理)时,在副本意外停止的情况下,可能存在已提交但尚未同步到磁盘的事务。这些事务可能会导致恢复过程失败,如果正在恢复的副本根据中继日志中的信息(最后一次同步到磁盘)尝试重新检索和应用事务而不是跳过它们。设置sync_relay_log=1对于多线程副本尤为重要,如果无法使用中继日志中的信息填补事务序列中的间隙,则恢复过程将失败。对于单线程副本,只有在应用程序元数据存储库中没有相关信息时,恢复过程才需要使用中继日志。
设置innodb_flush_log_at_trx_commit=1,在每个事务提交之前将InnoDB日志同步到磁盘。这个默认设置确保InnoDB表和InnoDB日志被保存在磁盘上,因此不再需要关于事务的中继日志中的信息。结合设置sync_relay_log=1,这个设置进一步确保InnoDB表和InnoDB日志的内容始终与中继日志的内容一致,以便在意外停止时,清除中继日志文件不会导致副本事务历史中存在无法填补的间隙。
设置relay_log_info_repository = TABLE,将复制 SQL 线程位置存储在InnoDB表mysql.slave_relay_log_info中,并与事务提交一起更新,以确保始终准确的记录。这个设置是 MySQL 8.0 的默认设置,FILE设置已被弃用。从 MySQL 8.0.23 开始,系统变量本身的使用已被弃用,因此可以省略它并允许其默认值。如果使用了FILE设置,这在早期版本中是默认设置,信息将存储在数据目录中的文件中,在事务应用后更新。这会导致与源的同步丢失的风险,具体取决于副本在处理事务的哪个阶段停止,甚至文件本身的损坏。使用设置relay_log_info_repository = FILE,无法保证恢复。
设置relay_log_recovery = ON,在服务器启动后立即启用自动中继日志恢复。这个全局变量默认为OFF,在运行时是只读的,但您可以在副本启动时使用–relay-log-recovery选项将其设置为ON,以应对副本意外停止。请注意,此设置会忽略现有的中继日志文件,以防它们损坏或不一致。中继日志恢复过程会启动一个新的中继日志文件,并从在应用程序元数据存储库中记录的复制 SQL 线程位置开始从源获取事务。副本的正常清理机制会随着时间删除先前的中继日志文件。
对于多线程复制,设置relay_log_recovery = ON会自动处理中继日志中已执行的事务序列中的任何不一致和间隙。当使用基于文件位置的复制时,这些间隙可能会发生。(有关更多详细信息,请参见第 19.5.1.34 节,“复制和事务不一致性”。)中继日志恢复过程使用与START REPLICA UNTIL SQL_AFTER_MTS_GAPS(或在 MySQL 8.0.22 之前,使用START SLAVE而不是START REPLICA)语句相同的方法处理间隙。当复制达到一致的无间隙状态时,中继日志恢复过程继续从源头开始获取进一步的事务,从复制 SQL 线程位置开始。当使用基于 GTID 的复制时,从 MySQL 8.0.18 开始,多线程复制首先检查MASTER_AUTO_POSITION是否设置为ON,如果是,则省略计算应跳过或不跳过的事务的步骤,因此旧的中继日志不需要用于恢复过程。
19.4.3 监视基于行的复制
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-rbr-monitoring.html
当使用基于行的复制时,通过性能模式仪表阶段监视复制应用程序(SQL)线程的当前进度,使您能够跟踪操作的处理并检查已完成的工作量和估计的工作量。当启用这些性能模式仪表阶段时,events_stages_current 表显示了应用程序线程的阶段及其进度。有关背景信息,请参阅第 29.12.5 节,“性能模式阶段事件表”。
要跟踪所有三种基于行的复制事件类型(写入、更新、删除)的进度:
通过执行以下命令启用三个性能模式阶段:
mysql> UPDATE performance_schema.setup_instruments SET ENABLED = \’YES\’
-> WHERE NAME LIKE \’stage/sql/Applying batch of row changes%\’;
等待一些事件被复制应用程序线程处理,然后通过查看events_stages_current表来检查进度。例如,要获取update事件的进度,请执行:
mysql> SELECT WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current
-> WHERE EVENT_NAME LIKE \’stage/sql/Applying batch of row changes (update)\’
如果启用了binlog_rows_query_log_events,则会将有关查询的信息存储在二进制日志中,并在processlist_info字段中公开。要查看触发此事件的原始查询:
mysql> SELECT db, processlist_state, processlist_info FROM performance_schema.threads
-> WHERE processlist_state LIKE \’stage/sql/Applying batch of row changes%\’ AND thread_id = N;
19.4.4 使用不同源和副本存储引擎的复制
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-diffengines.html
在复制过程中,原始源上的表和副本上的复制表使用不同的存储引擎类型并不重要。实际上,default_storage_engine 系统变量不会被复制。
这在复制过程中提供了许多好处,因为您可以针对不同的复制场景利用不同的引擎类型。例如,在典型的扩展场景中(参见 第 19.4.5 节,“使用复制进行扩展”),您希望在源上使用 InnoDB 表以利用事务功能,但在只读数据的副本上使用 MyISAM,因为不需要事务支持。在数据记录环境中使用复制时,您可能希望在副本上使用 Archive 存储引擎。
在源和副本上配置不同的引擎取决于您如何设置初始复制过程:
如果您使用 mysqldump 在源上创建数据库快照,您可以编辑转储文件文本以更改每个表使用的引擎类型。
另一个 mysqldump 的替代方法是在使用转储构建副本数据之前禁用不想在副本上使用的引擎类型。例如,您可以在副本上添加 –skip-federated 选项来禁用 FEDERATED 引擎。如果要创建的表没有特定的引擎存在,MySQL 将使用默认的引擎类型,通常是 InnoDB。(这要求未启用 NO_ENGINE_SUBSTITUTION SQL 模式。)如果您想以这种方式禁用其他引擎,您可能需要考虑构建一个专用的二进制文件,该文件仅支持您想要的引擎。
如果您使用原始数据文件(二进制备份)设置副本,则无法更改初始表格式。相反,在启动副本后,请使用 ALTER TABLE 来更改表类型。
对于新的源/复制复制设置,如果源上当前没有表,请在创建新表时避免指定引擎类型。
如果您已经在运行复制解决方案,并希望将现有表转换为另一种引擎类型,请按照以下步骤操作:
停止副本运行复制更新:
mysql> STOP SLAVE;
Or from MySQL 8.0.22:
mysql> STOP REPLICA;
这样可以在不中断的情况下更改引擎类型。
对每个要更改的表执行ALTER TABLE … ENGINE=\’*engine_type*\’。
重新开始复制过程:
mysql> START SLAVE;
或者,从 MySQL 8.0.22 开始:
mysql> START REPLICA;
尽管default_storage_engine变量不会被复制,但要注意包含引擎规范的CREATE TABLE和ALTER TABLE语句会正确地被复制到副本中。例如,在CSV表的情况下,如果执行以下语句:
mysql> ALTER TABLE csvtable ENGINE=\’MyISAM\’;
这个语句会被复制;副本上的表引擎类型会被转换为InnoDB,即使你之前已经将副本上的表类型更改为CSV之外的其他引擎。如果你想保留源和副本上的引擎差异,创建新表时应当小心使用default_storage_engine变量。例如,不要使用:
mysql> CREATE TABLE tablea (columna int) Engine=MyISAM;
使用这种格式:
mysql> SET default_storage_engine=MyISAM;
mysql> CREATE TABLE tablea (columna int);
在复制时,default_storage_engine变量会被忽略,CREATE TABLE语句会在副本上使用副本的默认引擎执行。
19.4.5 利用复制进行规模扩展
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-scaleout.html
您可以将复制用作规模扩展解决方案;也就是说,您希望在多个数据库服务器之间分配数据库查询负载,但在一定的限制范围内。
由于复制是从一个源到一个或多个副本的分发,因此在具有大量读取和少量写入/更新的环境中使用复制以实现规模扩展性效果最佳。大多数网站属于这一类别,用户在浏览网站、阅读文章、帖子或查看产品时进行操作。更新仅在会话管理期间发生,或在进行购买或向论坛添加评论/消息时发生。
在这种情况下,复制使您能够将读取操作分布到副本上,同时仍然使您的网络服务器在需要写入时与源进行通信。您可以在图 19.1 “利用复制提高规模扩展性”中查看此场景的示例复制布局。
图 19.1 利用复制提高规模扩展性
如果负责数据库访问的代码部分已经被正确抽象化/模块化,那么将其转换为运行在复制设置中应该是非常顺利和容易的。将数据库访问的实现更改为将所有写操作发送到源,将读取操作发送到源或副本。如果您的代码没有达到这种抽象化水平,设置一个复制系统将为您提供整理代码的机会和动力。首先创建一个实现以下功能的包装库或模块:
safe_writer_connect()
safe_reader_connect()
safe_reader_statement()
safe_writer_statement()
每个函数名称中的safe_表示该函数负责处理所有错误条件。您可以为函数使用不同的名称。重要的是要为读取连接、写入连接、执行读取和执行写入提供统一的接口。
然后将客户端代码转换为使用包装库。起初,这可能是一个痛苦和可怕的过程,但从长远来看是值得的。所有使用上述方法的应用程序都能够利用源/副本配置,甚至涉及多个副本。代码更容易维护,并且添加故障排除选项很简单。您只需要修改一个或两个函数(例如,记录每个语句花费的时间,或者哪个语句中出现了错误)。
如果您编写了大量代码,可能希望通过编写转换脚本来自动化转换任务。理想情况下,您的代码使用一致的编程风格约定。如果没有,那么最好重新编写它,或者至少通过手动规范化来使用一致的风格。
19.4.6 将不同的数据库复制到不同的副本
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-partitioning.html
可能存在这样的情况,您有一个单一的源服务器,并且希望将不同的数据库复制到不同的副本。例如,您可能希望将不同的销售数据分发给不同的部门,以帮助在数据分析期间分担负载。此布局的示例显示在图 19.2,“复制数据库以分离副本”中。
图 19.2 复制数据库以分离副本
您可以通过将源和副本配置为正常操作,然后通过在每个副本上使用–replicate-wild-do-table配置选项来限制每个副本处理的二进制日志语句,从而实现此分离。
重要提示
当使用基于语句的复制时,不应该使用–replicate-do-db来实现此目的,因为基于语句的复制会导致此选项的效果根据当前选择的数据库而变化。这也适用于混合格式复制,因为这样可以使用基于语句的格式复制一些更新。
但是,如果仅使用基于行的复制,则可以放心使用–replicate-do-db来实现此目的,因为在这种情况下,当前选择的数据库对选项的操作没有影响。
例如,要支持如图 19.2,“复制数据库以分离副本”所示的分离,您应该在执行START REPLICA之前,为每个副本配置如下:
副本 1 应使用–replicate-wild-do-table=databaseA.%。
副本 2 应使用–replicate-wild-do-table=databaseB.%。
副本 3 应使用–replicate-wild-do-table=databaseC.%。
在这种配置中,每个副本都接收源自源服务器的整个二进制日志,但仅执行二进制日志中适用于副本上生效的–replicate-wild-do-table选项包含的数据库和表的事件。
如果您有必须在复制开始之前同步到副本的数据,则有多种选择:
将所有数据同步到每个副本,并删除您不想保留的数据库、表或两者。
使用mysqldump为每个数据库创建单独的转储文件,并在每个副本上加载适当的转储文件。
使用原始数据文件转储,并仅包含每个副本所需的特定文件和数据库。
注意
这对InnoDB数据库不起作用,除非您使用innodb_file_per_table。
19.4.7 改进复制性能
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-performance.html
随着连接到源的副本数量的增加,负载虽然很小,但也会增加,因为每个副本都使用客户端连接到源。此外,由于每个副本必须接收源的二进制日志的完整副本,因此源上的网络负载也可能增加并创建瓶颈。
如果您正在使用大量与一个源连接的副本,并且该源也在忙于处理请求(例如,作为扩展解决方案的一部分),那么您可能希望改进复制过程的性能。
改进复制过程性能的一种方法是创建一个更深层次的复制结构,使源只能复制到一个副本,而其余副本则连接到此主要副本以满足各自的复制需求。此结构示例如 图 19.3,“使用额外的复制源以提高性能” 中所示。
图 19.3 使用额外的复制源以提高性能
要使其正常工作,您必须按以下方式配置 MySQL 实例:
源 1 是所有更改和更新都写入数据库的主要源。两个源服务器都启用了二进制日志记录,这是默认设置。
源 2 是向其余副本提供复制功能的服务器源 1 的副本。源 2 是唯一被允许连接到源 1 的机器。源 2 启用了 –log-slave-updates 选项(默认情况下启用)。通过此选项,源 1 的复制指令也会被写入源 2 的二进制日志中,然后可以被复制到真正的副本中。
副本 1、副本 2 和副本 3 充当源 2 的副本,并复制来自源 2 的信息,实际上包括在源 1 上记录的升级。
上述解决方案减少了主要源上的客户端负载和网络接口负载,应该提高主要源作为直接数据库解决方案时的整体性能。
如果您的副本在源上跟不上复制过程,那么有多种选择可供选择:
如果可能的话,将中继日志和数据文件放在不同的物理驱动器上。为此,请设置relay_log系统变量以指定中继日志的位置。
如果读取二进制日志文件和中继日志文件的磁盘 I/O 活动较大,考虑增加rpl_read_size系统变量的值。该系统变量控制从日志文件中读取的最小数据量,增加该值可能会减少文件读取和 I/O 停顿,尤其是当文件数据当前未被操作系统缓存时。请注意,为从二进制日志和中继日志文件读取的每个线程分配了与此值大小相同的缓冲区,包括源上的转储线程和副本上的协调器线程。因此,设置一个较大的值可能会影响服务器的内存消耗。
如果副本比源慢得多,您可能希望将不同数据库的复制责任分配给不同的副本。参见 Section 19.4.6, “将不同数据库复制到不同副本”。
如果您的源使用事务,并且您不关心副本上的事务支持,请在副本上使用MyISAM或其他非事务引擎。参见 Section 19.4.4, “使用不同源和副本存储引擎进行复制”。
如果您的副本不充当源,并且已经有潜在的解决方案确保在发生故障时可以启动源,则可以在副本上禁用系统变量log_replica_updates(从 MySQL 8.0.26 开始)或log_slave_updates(MySQL 8.0.26 之前)。这可以防止“愚蠢”的副本也将其执行的事件记录到自己的二进制日志中。
19.4.8 故障转移期间切换源
原文:dev.mysql.com/doc/refman/8.0/en/replication-solutions-switch.html
你可以使用CHANGE REPLICATION SOURCE TO语句(MySQL 8.0.23 之前为 CHANGE MASTER TO 选项),这是默认设置。如果您没有使用 GTIDs 进行复制,那么复制品还应该运行 –log-slave-updates=OFF(记录复制品更新是默认设置)。这样,复制品就可以在不重新启动复制品的情况下准备成为源。假设您拥有 图 19.4,“使用复制实现冗余,初始结构” 中显示的结构。
图 19.4 使用复制实现冗余,初始结构
在这个图中,Source 拥有源数据库,Replica* 主机是复制品,Web Client 机器正在发出数据库读取和写入。只发出读取的 Web 客户端(通常连接到复制品)没有显示,因为它们在故障发生时不需要切换到新服务器。有关读写扩展复制结构的更详细示例,请参见 19.4.5 “使用复制进行扩展”。
每个 MySQL 副本(副本 1、副本 2和副本 3)都是启用二进制日志记录的副本,并且使用–log-slave-updates=OFF。因为当指定–log-slave-updates=OFF时,从源接收的更新不会写入二进制日志,所以每个副本上的二进制日志最初是空的。如果由于某种原因Source不可用,您可以选择其中一个副本成为新的源。例如,如果选择副本 1,则所有Web Clients应重定向到副本 1,它会将更新写入其二进制日志。然后副本 2和副本 3应从副本 1复制。
运行副本时使用–log-slave-updates=OFF的原因是为了防止副本在您导致其中一个副本成为新源时收到更新两次。如果副本 1启用了–log-slave-updates,这是默认设置,它会将从Source接收的任何更新写入自己的二进制日志。这意味着当副本 2从Source更改为副本 1作为其源时,它可能会收到已经从Source接收过的副本 1的更新。
确保所有副本都已处理其中继日志中的任何语句。在每个副本上,发出STOP REPLICA IO_THREAD命令,然后检查SHOW PROCESSLIST的输出,直到看到Has read all relay log。当所有副本都满足此条件时,它们可以重新配置到新的设置。在晋升为源的副本副本 1上,发出STOP REPLICA和RESET MASTER命令。
在其他副本副本 2和副本 3上,使用STOP REPLICA和CHANGE REPLICATION SOURCE TO SOURCE_HOST=\’Replica1\’或CHANGE MASTER TO MASTER_HOST=\’Replica1\’(其中\’Replica1\’代表副本 1的真实主机名)。要使用CHANGE REPLICATION SOURCE TO,添加有关如何从副本 2或副本 3连接到副本 1的所有信息(user、password、port)。在此场景中发出该语句时,无需指定要从中读取的副本 1二进制日志文件的名称或位置,因为第一个二进制日志文件和位置 4 是默认值。最后,在副本 2和副本 3上执行START REPLICA。
一旦新的复制设置就位,你需要告诉每个 Web 客户端 将其语句发送到 Replica 1。从那时起,Web 客户端 发送到 Replica 1 的所有更新都将写入 Replica 1 的二进制日志中,其中包含自 Source 不可用以来发送到 Replica 1 的每个更新。
结果显示的服务器结构如 图 19.5,“使用复制实现冗余,在源故障后” 所示。
图 19.5 使用复制实现冗余,在源故障后
当 Source 再次可用时,你应该将其设置为 Replica 1 的副本。为此,在 Source 上发出与之前在 Replica 2 和 Replica 3 上发出的相同的 CHANGE REPLICATION SOURCE TO(或 CHANGE MASTER TO)语句。然后,Source 成为 Replica 1 的副本,并接收它在离线时错过的 Web 客户端 写入数据。
要使 Source 再次成为源,请按照上述步骤操作,就好像 Replica 1 不可用,而 Source 将成为新的源一样。在此过程中,不要忘记在将 Replica 1、Replica 2 和 Replica 3 设置为 Source 的副本之前,在 Source 上运行 RESET MASTER。如果你忘记了这一步,副本可能会接收到自 Source 不可用之前的时间点起的旧写入数据。
你应该意识到副本之间没有同步,即使它们共享相同的源,因此某些副本可能比其他副本领先很多。这意味着在某些情况下,前面示例中概述的过程可能不会按预期工作。然而,在实践中,所有副本上的中继日志应该相对接近。
保持应用程序了解源位置的一种方法是为源主机设置动态 DNS 条目。使用 BIND,你可以使用 nsupdate 动态更新 DNS。
19.4.9 利用异步连接故障转移切换源和副本
原文:dev.mysql.com/doc/refman/8.0/en/replication-asynchronous-connection-failover.html
19.4.9.1 源的异步连接故障转移
19.4.9.2 副本的异步连接故障转移
从 MySQL 8.0.22 开始,您可以使用异步连接故障转移机制在现有副本到源的连接失败后自动建立与新源的异步(源到副本)复制连接。异步连接故障转移机制可用于使副本与共享数据的多个 MySQL 服务器或服务器组保持同步。潜在源服务器列表存储在副本上,在连接失败时,根据您设置的加权优先级从列表中选择新源。
从 MySQL 8.0.23 开始,异步连接故障转移机制还支持组复制拓扑结构,通过自动监视组成员变化并区分主服务器和次要服务器。当您将组成员添加到源列表并将其定义为受控组的一部分时,异步连接故障转移机制会更新源列表以使其与成员变化保持一致,随着成员加入或离开自动添加和删除组成员。仅使用在线占多数的组成员进行连接和获取状态。即使最后剩下的受控组成员离开组,也不会自动删除,以保持受控组的配置。但是,如果不再需要,可以手动删除受控组。
从 MySQL 8.0.27 开始,异步连接故障转移机制还可以使作为受控复制组一部分的副本在当前接收者(组的主节点)失败时自动重新连接到发送者。此功能与组复制一起使用,在配置为单主模式的组上工作,其中组的主节点是使用该机制的副本的复制通道。该功能旨在使一组发送者和一组接收者即使某些成员暂时不可用也保持同步。它还将一组接收者与一个或多个不属于受控组的发送者同步。不属于复制组的副本无法使用此功能。
使用异步连接故障转移机制的要求如下:
GTIDs 必须在源端和副本端使用 (gtid_mode=ON),并且必须在副本端启用 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 语句的 SOURCE_AUTO_POSITION | MASTER_AUTO_POSITION 选项,以便使用 GTID 自动定位连接到源端。
在通道的源列表中,所有源服务器上必须存在相同的复制用户帐户和密码。此帐户用于连接到每个源端。您可以为不同的通道设置不同的帐户。
复制用户帐户必须在 Performance Schema 表上具有 SELECT 权限,例如,通过发出 GRANT SELECT ON performance_schema.* TO \’*repl_user*\’;。
由于需要在备用源端的自动重启中使用,因此不能在用于启动复制的语句中指定复制用户帐户和密码。必须在副本端使用 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO 语句为通道设置这些信息,并记录在复制元数据存储库中。
如果异步连接故障转移机制正在使用的通道位于 Group Replication 单主模式组的主服务器上,在 MySQL 8.0.27 中,默认情况下也会激活副本之间的异步连接故障转移。在这种情况下,必须在复制组中的所有次要服务器以及任何新加入的成员上设置复制通道和复制用户帐户和密码。如果使用 MySQL 的克隆功能提供新服务器,则所有这些都会自动发生。
重要
如果您不希望在这种情况下副本之间发生异步连接故障转移,请通过使用 group_replication_disable_member_action 函数为组禁用成员操作 mysql_start_failover_channels_if_primary 来禁用它。当禁用该功能时,您无需在次要组成员上配置复制通道,但如果主服务器下线或进入错误状态,则通道的复制将停止。
从 MySQL Shell 8.0.27 和 MySQL 8.0.27 开始,MySQL InnoDB ClusterSet 可用于为 InnoDB Cluster 部署提供灾难容忍性,方法是将主 InnoDB Cluster 与其在不同位置(如不同数据中心)的一个或多个副本链接起来。考虑使用这种解决方案来简化新的多组部署的设置,用于复制、故障切换和灾难恢复。您可以将现有的 Group Replication 部署作为 InnoDB Cluster 采用。
InnoDB ClusterSet 和 InnoDB Cluster 旨在抽象和简化设置、管理、监控、恢复和修复复制组的过程。InnoDB ClusterSet 自动管理从主集群到副本集群的复制,使用专用的 ClusterSet 复制通道。您可以使用管理员命令在主集群不正常运行时触发受控切换或紧急故障转移。在需求发生变化时,可以在初始设置后轻松地向 InnoDB ClusterSet 部署添加或删除服务器和组。有关更多信息,请参阅 MySQL InnoDB ClusterSet。
dev.mysql.com/doc/refman/8.0/en/replication-asynchronous-connection-failover-source.html
19.4.9.1 异步连接源的故障转移
要激活复制通道的异步连接故障转移,在CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(MySQL 8.0.23 之前)中设置SOURCE_CONNECTION_AUTO_FAILOVER=1。通道必须使用 GTID 自动定位(SOURCE_AUTO_POSITION = 1 | MASTER_AUTO_POSITION = 1)。
重要提示
当与源的现有连接失败时,复制品首先重试由CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的SOURCE_RETRY_COUNT | MASTER_RETRY_COUNT选项指定的次数。尝试之间的间隔由SOURCE_CONNECT_RETRY | MASTER_CONNECT_RETRY选项设置。当这些尝试耗尽时,异步连接故障转移机制接管。请注意,这些选项的默认值是为了连接到单个源而设计的,使复制品在 60 天内重试相同的连接。为了确保可以及时激活异步连接故障转移机制,请将SOURCE_RETRY_COUNT | MASTER_RETRY_COUNT和SOURCE_CONNECT_RETRY | MASTER_CONNECT_RETRY设置为最小值,只允许与同一源进行少量重试尝试,以防连接故障是由瞬时网络中断引起的。适当的值是SOURCE_RETRY_COUNT=3 | MASTER_RETRY_COUNT=3和SOURCE_CONNECT_RETRY=10 | MASTER_CONNECT_RETRY=10,使复制品在 10 秒间隔内重试 3 次连接。
您还需要为复制通道设置源列表,以指定可用于故障转移的源。您可以使用asynchronous_connection_failover_add_source和asynchronous_connection_failover_delete_source函数来设置和管理源列表,以添加和删除单个复制源服务器。要添加和删除受管理的服务器组,请改用asynchronous_connection_failover_add_managed和asynchronous_connection_failover_delete_managed函数。
函数命名相关复制通道,并指定要添加到或从通道源列表中删除的 MySQL 实例的主机名、端口号、网络命名空间和加权优先级(1-100,100 为最高优先级)。对于受管组,您还需要指定受管服务的类型(目前仅有 Group Replication 可用),以及受管组的标识符(对于 Group Replication,这是group_replication_group_name系统变量的值)。当您添加受管组时,只需添加一个组成员,副本会自动添加当前组成员的其余部分。当您删除受管组时,将一起删除整个组。
在 MySQL 8.0.22 中,异步连接故障转移机制在副本与源的连接失败后被激活,并发出START REPLICA语句尝试连接到新源。在此版本中,如果由于源停止或由于网络故障导致复制接收线程停止,连接将转移。在其他情况下,例如当复制线程被STOP REPLICA语句停止时,连接不会转移。
从 MySQL 8.0.23 开始,异步连接故障转移机制还会在源列表中另一个可用服务器具有更高优先级(权重)设置时转移连接。此功能确保副本始终连接到最合适的源服务器,并适用于受管组和单个(非受管)服务器。对于受管组,源的权重根据其是主服务器还是从服务器而分配。因此,假设您设置受管组以给予主服务器更高的权重,从服务器更低的权重,当主服务器更改时,新主服务器被分配更高的权重,因此副本将连接到新主服务器。如果当前连接的受管源服务器离开受管组,或者不再是受管组中的大多数,异步连接故障转移机制还会更改连接。
在连接故障时,通道的源列表中列出的备用源中具有最高优先级(权重)设置的源将被选择用于第一次连接尝试。 复制品首先检查它是否可以连接到源服务器,或者在管理组的情况下,源服务器在组中是否具有ONLINE状态(而不是RECOVERING或不可用)。 如果最高加权源不可用,则复制品将按权重降序尝试所有列出的源,然后再从最高加权源开始。 如果多个源具有相同的权重,则复制品会随机排序它们。 如果复制品需要重新开始遍历列表,则它会包括并重试原始连接故障发生的源。
源列表存储在mysql.replication_asynchronous_connection_failover和mysql.replication_asynchronous_connection_failover_managed表中,并可以在性能模式replication_asynchronous_connection_failover和replication_asynchronous_connection_failover_managed表中查看。 复制品使用监视线程跟踪管理组的成员资格并更新源列表(thread/sql/replica_monitor)。 CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的SOURCE_CONNECTION_AUTO_FAILOVER选项设置和源列表在远程克隆操作期间传输到复制品的克隆中。
原文:dev.mysql.com/doc/refman/8.0/en/replication-asynchronous-connection-failover-replica.html
19.4.9.2 副本的异步连接故障转移
在 MySQL 8.0.27 及更高版本中,当你在复制通道上设置SOURCE_CONNECTION_AUTO_FAILOVER=1时,副本的异步连接故障转移将自动激活于 Group Replication 主服务器上。该功能旨在设计一个发送者组和一个接收者组,即使一些成员暂时不可用,它们也能保持同步。当该功能处于活动状态并正确配置时,如果正在复制的主服务器离线或进入错误状态,新的主服务器在选举时将在同一通道上开始复制。新的主服务器使用通道的源列表来选择具有最高优先级(权重)设置的源,这可能与原始源不同。
要配置此功能,必须在复制组中的所有成员服务器以及任何新加入的成员上设置复制通道和通道的复制用户帐户和密码。确保SOURCE_RETRY_COUNT和SOURCE_CONNECT_RETRY设置为允许少量重试尝试的最小数字,例如 3 和 10。您可以使用CHANGE REPLICATION SOURCE TO设置复制通道,或者如果新服务器是使用 MySQL 的克隆功能进行配置的,则所有这些都会自动发生。当新成员加入时,主服务器会向组成员广播通道的SOURCE_CONNECTION_AUTO_FAILOVER设置。如果您稍后在主服务器上禁用通道的SOURCE_CONNECTION_AUTO_FAILOVER,这也会广播到辅助服务器,并且它们会更改通道的状态以匹配。
注意
在单主模式下参与组的服务器必须使用–skip-replica-start=ON启动。否则,服务器无法作为辅助服务器加入组。
副本的异步连接故障转移是通过 Group Replication 成员操作mysql_start_failover_channels_if_primary来激活和停用的,默认情况下启用。您可以通过在主服务器上禁用该成员操作来为整个组禁用它,使用group_replication_disable_member_action函数,如下例所示:
mysql> SELECT group_replication_disable_member_action(\”mysql_start_failover_channels_if_primary\”, \”AFTER_PRIMARY_ELECTION\”);
该功能只能在主服务器上更改,并且必须为整个组启用或禁用,因此不能让一些成员提供故障转移,而其他成员不提供。当禁用mysql_start_failover_channels_if_primary成员操作时,次要成员不需要配置频道,但如果主服务器下线或进入错误状态,则该频道的复制将停止。请注意,如果有多个具有SOURCE_CONNECTION_AUTO_FAILOVER=1的频道,则成员操作将覆盖所有频道,因此它们不能通过该方法单独启用或禁用。在主服务器上将SOURCE_CONNECTION_AUTO_FAILOVER=0设置为禁用单个频道。
当频道具有SOURCE_CONNECTION_AUTO_FAILOVER=1时,源列表会在所有组成员加入时广播,并在更改时也会广播。无论这些源是否是一个受管理的组,其成员资格是否会自动更新,或者是使用asynchronous_connection_failover_add_source(),asynchronous_connection_failover_delete_source(),asynchronous_connection_failover_add_managed(),或asynchronous_connection_failover_delete_managed()手动添加或更改。所有组成员都会收到当前源列表,记录在mysql.replication_asynchronous_connection_failover和mysql.replication_asynchronous_connection_failover_managed表中。因为源不必在受管理的组中,所以您可以设置该功能以将一组接收器与一个或多个备用独立发件人同步,甚至是单个发件人。不属于复制组的独立副本无法使用此功能。
19.4.10 半同步复制
原文:dev.mysql.com/doc/refman/8.0/en/replication-semisync.html
19.4.10.1 安装半同步复制
19.4.10.2 配置半同步复制
19.4.10.3 半同步复制监视
除了内置的异步复制外,MySQL 8.0 还支持由插件实现的半同步复制接口。本节讨论了什么是半同步复制以及它是如何工作的。接下来的章节将涵盖半同步复制的管理接口以及如何安装、配置和监视它。
MySQL 默认情况下是异步复制。源将事件写入其二进制日志,副本在准备好时请求这些事件。源不知道副本是否何时检索和处理事务,并且不能保证任何事件是否会到达任何副本。使用异步复制时,如果源崩溃,它已经提交的事务可能尚未传输至任何副本。在这种情况下,从源切换到副本可能导致切换到相对于源缺少事务的服务器。
使用完全同步复制时,当源提交事务时,所有副本在源返回执行事务的会话之前也已经提交了该事务。完全同步复制意味着可以随时从源切换到任何副本。完全同步复制的缺点是可能会有很多延迟来完成一个事务。
半同步复制介于异步和完全同步复制之间。源会等待至少一个副本接收并记录事件(所需副本数量可配置),然后提交事务。源不会等待所有副本确认接收,并且只需要副本的确认,而不需要事件在副本端完全执行和提交。因此,半同步复制保证了如果源崩溃,它已经提交的所有事务都已传输至至少一个副本。
与异步复制相比,半同步复制提供了改进的数据完整性,因为当提交成功返回时,可以知道数据至少存在于两个地方。在半同步源接收到所需数量的副本的确认之前,事务会被暂停并且不会被提交。
与完全同步复制相比,半同步复制更快,因为它可以配置以平衡数据完整性要求(确认接收事务的副本数量)与提交速度之间的要求,由于需要等待副本,提交速度较慢。
重要提示
使用半同步复制,如果源崩溃并进行故障转移到副本,则失败的源不应重新用作复制源,并应丢弃。它可能有一些事务尚未被任何副本确认,因此在故障转移之前未提交。
如果您的目标是实现一个容错的复制拓扑结构,其中所有服务器以相同顺序接收相同的事务,并且崩溃的服务器可以重新加入组并自动更新,您可以使用组复制来实现这一目标。有关详细信息,请参见第二十章,组复制。
与异步复制相比,半同步复制的性能影响是为了增加数据完整性而进行的权衡。减速的量至少是将提交发送到副本并等待副本确认接收的 TCP/IP 往返时间。这意味着半同步复制最适合在快速网络上通信的近距离服务器,并且对于在慢速网络上通信的远程服务器最不利。半同步复制还通过限制二进制日志事件从源到副本发送的速度来对繁忙会话进行速率限制。当一个用户太忙时,这会减慢速度,在某些部署情况下可能会很有用。
源和其副本之间的半同步复制操作如下:
当副本连接到源时,副本指示其是否支持半同步。
如果在源端启用了半同步复制并且至少有一个半同步副本,则在源上执行事务提交的线程将被阻塞,并等待至少一个半同步副本确认已接收到该事务的所有事件,或者直到超时发生。
副本仅在将事件写入其中继日志并刷新到磁盘后才确认接收到事务的事件。
如果超时发生而没有任何副本确认事务,则源将恢复为异步复制。当至少一个半同步副本赶上时,源将恢复为半同步复制。
必须在源端和副本端启用半同步复制。如果在源端禁用了半同步复制,或者在源端启用了半同步复制但没有在任何副本上启用,则源将使用异步复制。
当源正在阻塞(等待来自副本的确认)时,它不会返回到执行事务的会话。当阻塞结束时,源会返回到会话,然后可以继续执行其他语句。此时,在源端事务已经提交,并且至少一个副本已经确认接收到其事件。源在返回到会话之前必须接收每个事务的副本确认数量是可配置的,默认为一个确认(参见 Section 19.4.10.2, “Configuring Semisynchronous Replication”)。
阻塞也会发生在写入二进制日志的回滚之后,这种情况发生在回滚修改非事务表的事务时。即使对于事务表来说回滚的事务没有影响,但对于非事务表的修改无法回滚,必须发送到副本中,因此回滚的事务会被记录。
对于不在事务上下文中发生的语句(也就是说,没有使用START TRANSACTION或SET autocommit = 0启动事务时),自动提交被启用,每个语句都会隐式提交。在半同步复制中,源会为每个这样的语句阻塞,就像为显式事务提交一样。
默认情况下,源在将二进制日志同步到磁盘后等待副本确认事务接收,但在将事务提交到存储引擎之前。作为替代方案,您可以配置源,使其在将事务提交到存储引擎后等待副本确认,使用rpl_semi_sync_source_wait_point或rpl_semi_sync_master_wait_point系统变量。此设置会影响复制特性和客户端在源端可以看到的数据。有关更多信息,请参见 Section 19.4.10.2, “Configuring Semisynchronous Replication”。
从 MySQL 8.0.23 开始,您可以通过启用系统变量replication_sender_observe_commit_only和replication_optimize_for_static_plugin_config来提高半同步复制的性能,前者限制回调,后者添加共享锁并避免不必要的锁获取。这些设置在副本数量增加时非常有帮助,因为锁争用可能会降低性能。半同步复制源服务器还可以通过启用这些系统变量获得性能优势,因为它们使用与副本相同的锁定机制。
原文:dev.mysql.com/doc/refman/8.0/en/replication-semisync-installation.html
19.4.10.1 安装半同步复制
半同步复制是使用插件实现的,这些插件必须安装在源服务器和副本上,以使半同步复制在实例上可用。 源和副本有不同的插件。 安装插件后,您可以通过与之关联的系统变量来控制它。 仅当关联的插件已安装时,这些系统变量才可用。
本节描述了如何安装半同步复制插件。 有关安装插件的一般信息,请参见 Section 7.6.1, “安装和卸载插件”。
要使用半同步复制,必须满足以下要求:
安装插件的能力需要支持动态加载的 MySQL 服务器。 要验证这一点,请检查have_dynamic_loading 系统变量的值是否为 YES。 二进制发行版应支持动态加载。
复制必须已经正常工作,请参见 Section 19.1, “配置复制”。
不得配置多个复制通道。 半同步复制仅与默认复制通道兼容。 请参见 Section 19.2.2, “复制通道”。
从 MySQL 8.0.26 开始,提供了实现半同步复制的插件的新版本,一个用于源服务器,一个用于副本。 新插件在系统变量和状态变量中将“主”和“从”替换为“源”和“副本”,您可以安装这些版本而不是旧版本。 不能在实例上同时安装相关插件的新旧版本。 如果使用新版本的插件,则新的系统变量和状态变量可用,但旧的不可用。 如果使用旧版本的插件,则旧的系统变量和状态变量可用,但新的不可用。
插件库文件的文件名后缀因平台而异(例如,Unix 和类 Unix 系统使用.so,Windows 使用.dll)。 插件和库文件的名称如下:
源服务器,旧术语:rpl_semi_sync_master 插件(semisync_master.so 或 semisync_master.dll 库)
源服务器,新术语(从 MySQL 8.0.26 开始):rpl_semi_sync_source 插件(semisync_source.so 或 semisync_source.dll 库)
复制品,旧术语:rpl_semi_sync_slave 插件(semisync_slave.so 或 semisync_slave.dll 库)
复制,新术语(自 MySQL 8.0.26 起):rpl_semi_sync_replica插件(semisync_replica.so或semisync_replica.dll库)
要被源服务器或复制服务器使用,适当的插件库文件必须位于 MySQL 插件目录中(由plugin_dir系统变量命名的目录)。必要时,通过在服务器启动时设置plugin_dir的值来配置插件目录位置。源插件库文件必须存在于源服务器的插件目录中。复制插件库文件必须存在于每个复制服务器的插件目录中。
要设置半同步复制,请使用以下说明。这里提到的INSTALL PLUGIN、SET GLOBAL、STOP REPLICA和START REPLICA语句需要REPLICATION_SLAVE_ADMIN权限(或已弃用的SUPER权限)。
加载插件,请在源端和每个要进行半同步的复制端上使用INSTALL PLUGIN语句,根据需要调整您平台的.so后缀。
在源端:
INSTALL PLUGIN rpl_semi_sync_master SONAME \’semisync_master.so\’;
Or from MySQL 8.0.26:
INSTALL PLUGIN rpl_semi_sync_source SONAME \’semisync_source.so\’;
在每个复制端:
INSTALL PLUGIN rpl_semi_sync_slave SONAME \’semisync_slave.so\’;
Or from MySQL 8.0.26:
INSTALL PLUGIN rpl_semi_sync_replica SONAME \’semisync_replica.so\’;
如果在 Linux 上尝试安装插件时出现类似于此处所示的错误,则必须安装libimf:
mysql> INSTALL PLUGIN rpl_semi_sync_source SONAME \’semisync_source.so\’;
ERROR 1126 (HY000): Can\’t open shared library
\’/usr/local/mysql/lib/plugin/semisync_source.so\’
(errno: 22 libimf.so: cannot open shared object file:
No such file or directory)
您可以从dev.mysql.com/downloads/os-linux.html获取libimf。
要验证插件安装,请检查信息模式PLUGINS表,或使用SHOW PLUGINS语句(参见第 7.6.2 节,“获取服务器插件信息”)。例如:
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE \’%semi%\’;
+———————-+—————+
| PLUGIN_NAME | PLUGIN_STATUS |
+———————-+—————+
| rpl_semi_sync_source | ACTIVE |
+———————-+—————+
如果插件初始化失败,请检查服务器错误日志以获取诊断消息。
安装半同步复制插件后,默认情况下是禁用的。必须在源端和复制端都启用插件才能启用半同步复制。如果只有一侧启用,则复制是异步的。要启用插件,请在运行时使用SET GLOBAL设置适当的系统变量,或在命令行或选项文件中在服务器启动时设置。例如:
On the source:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
Or from MySQL 8.0.26 with the rpl_semi_sync_source plugin:
SET GLOBAL rpl_semi_sync_source_enabled = 1;
On each replica:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Or from MySQL 8.0.26 with the rpl_semi_sync_replica plugin:
SET GLOBAL rpl_semi_sync_replica_enabled = 1;
如果您在运行时在副本上启用半同步复制,您还必须启动复制 I/O(接收器)线程(如果已经运行,则首先停止它),以使副本连接到源并注册为半同步副本:
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
Or from MySQL 8.0.22:
STOP REPLICA IO_THREAD;
START REPLICA IO_THREAD;
如果复制 I/O(接收器)线程已经在运行,而您没有重新启动它,副本将继续使用异步复制。
在选项文件中列出的设置在每次服务器启动时生效。例如,您可以在源服务器和副本服务器的my.cnf文件中设置变量如下:
On the source:
[mysqld]
rpl_semi_sync_master_enabled=1
Or from MySQL 8.0.26 with the rpl_semi_sync_source plugin:
rpl_semi_sync_source_enabled=1
On each replica:
[mysqld]
rpl_semi_sync_slave_enabled=1
Or from MySQL 8.0.26 with the rpl_semi_sync_source plugin:
rpl_semi_sync_replica_enabled=1
您可以使用安装插件时提供的系统变量来配置半同步复制插件的行为。有关关键系统变量的信息,请参见 Section 19.4.10.2, “Configuring Semisynchronous Replication”。
NAME ‘semisync_source.so’;
ERROR 1126 (HY000): Can’t open shared library
‘/usr/local/mysql/lib/plugin/semisync_source.so’
(errno: 22 libimf.so: cannot open shared object file:
No such file or directory)
您可以从[`dev.mysql.com/downloads/os-linux.html`](https://dev.mysql.com/downloads/os-linux.html)获取`libimf`。
要验证插件安装,请检查信息模式`PLUGINS`表,或使用`SHOW PLUGINS`语句(参见第 7.6.2 节,“获取服务器插件信息”)。例如:
“`sql
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE \’%semi%\’;
+———————-+—————+
| PLUGIN_NAME | PLUGIN_STATUS |
+———————-+—————+
| rpl_semi_sync_source | ACTIVE |
+———————-+—————+
如果插件初始化失败,请检查服务器错误日志以获取诊断消息。
安装半同步复制插件后,默认情况下是禁用的。必须在源端和复制端都启用插件才能启用半同步复制。如果只有一侧启用,则复制是异步的。要启用插件,请在运行时使用SET GLOBAL设置适当的系统变量,或在命令行或选项文件中在服务器启动时设置。例如:
On the source:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
Or from MySQL 8.0.26 with the rpl_semi_sync_source plugin:
SET GLOBAL rpl_semi_sync_source_enabled = 1;
On each replica:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Or from MySQL 8.0.26 with the rpl_semi_sync_replica plugin:
SET GLOBAL rpl_semi_sync_replica_enabled = 1;
如果您在运行时在副本上启用半同步复制,您还必须启动复制 I/O(接收器)线程(如果已经运行,则首先停止它),以使副本连接到源并注册为半同步副本:
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
Or from MySQL 8.0.22:
STOP REPLICA IO_THREAD;
START REPLICA IO_THREAD;
如果复制 I/O(接收器)线程已经在运行,而您没有重新启动它,副本将继续使用异步复制。
在选项文件中列出的设置在每次服务器启动时生效。例如,您可以在源服务器和副本服务器的my.cnf文件中设置变量如下:
On the source:
[mysqld]
rpl_semi_sync_master_enabled=1
Or from MySQL 8.0.26 with the rpl_semi_sync_source plugin:
rpl_semi_sync_source_enabled=1
On each replica:
[mysqld]
rpl_semi_sync_slave_enabled=1
Or from MySQL 8.0.26 with the rpl_semi_sync_source plugin:
rpl_semi_sync_replica_enabled=1
您可以使用安装插件时提供的系统变量来配置半同步复制插件的行为。有关关键系统变量的信息,请参见 Section 19.4.10.2, “Configuring Semisynchronous Replication”。
#以上关于MySQL8 中文参考(七十九)的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92418.html