12.3.10. MySQL复制
这部分描述了基于二进制日志文件位置方法的 MySQL 服务器之间的复制,其中作为源(数据库更改发生地)运行的 MySQL 实例将更新和更改作为“事件”写入二进制日志。二进制日志中的信息根据所记录的数据库更改以不同的日志格式存储。副本被配置为从源读取二进制日志,并在副本的本地数据库上执行二进制日志中的事件。
每个副本都会收到二进制日志内容的完整副本。由副本决定应执行二进制日志中的哪些语句。除非另有指定,否则源的二进制日志中的所有事件都会在副本上执行。如果需要,您可以配置副本只处理适用于特定数据库或表的事件。
每个副本都会记录二进制日志的坐标:它从源读取和处理的文件名以及文件中的位置。这意味着多个副本可以连接到源并执行同一个二进制日志的不同部分。由于副本控制这个过程,单个副本可以连接和断开服务器,而不影响源的操作。此外,因为每个副本记录了二进制日志中的当前位置,副本可以断开连接、重新连接然后继续处理。
源和每个副本都必须配置一个唯一的 ID(使用 server_id 系统变量)。此外,每个副本必须配置关于源的主机名、日志文件名和文件中的位置的信息。这些详细信息可以在 MySQL 会话中使用 CHANGE REPLICATION SOURCE TO 语句(从 MySQL 8.0.23 开始)或 CHANGE MASTER TO 语句(在 MySQL 8.0.23 之前)在副本上进行控制。详细信息存储在副本的连接元数据存储库中(参见第19.2.4节,“中继日志和复制元数据存储库”)。
12.3.10.1. 设置复制源配置
SET GLOBAL server_id = 2;
如何组织和选择服务器 ID 取决于您,只要每个服务器 ID 都与复制拓扑中其他服务器的 ID 不同即可。请注意,如果之前为服务器 ID 设置了 0(这是早期版本中的默认值),则必须重新启动服务器以使用新的非零服务器 ID 初始化源。否则,当您更改服务器 ID 时,不需要重新启动服务器,除非您进行其他需要重新启动的配置更改。
源上必须启用二进制日志,因为二进制日志是从源复制更改到其副本的基础。默认情况下启用二进制日志(log_bin 系统变量设置为 ON)。–log-bin 选项告诉服务器用于二进制日志文件的基本名称。建议您指定此选项,以便为二进制日志文件提供一个非默认的基本名称,这样如果主机名更改,您可以继续使用相同的二进制日志文件名(参见第 B.3.7 节,“MySQL 中的已知问题”)。如果之前使用 –skip-log-bin 选项在源上禁用了二进制日志,则必须在不使用此选项的情况下重新启动服务器以启用二进制日志。
为了在使用 InnoDB 和事务的复制设置中获得最大的持久性和一致性,您应在源的 my.cnf 文件中使用 innodb_flush_log_at_trx_commit=1 和 sync_binlog=1。
确保源上的 skip_networking 系统变量未启用。如果禁用了网络,副本将无法与源通信,复制将失败。
12.3.10.2. 设置副本
每个副本必须具有一个唯一的服务器 ID,该 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_updates 或 log_slave_updates 系统变量默认情况下是启用的。
如果您需要在副本上禁用二进制日志记录或副本更新记录,可以通过为副本指定 –skip-log-bin 和 –log-replica-updates=OFF(或 –log-slave-updates=OFF)选项来实现。如果决定在副本上重新启用这些功能,删除相关选项并重新启动服务器。
12.3.10.3. 创建用于复制的用户
每个副本都使用一个MySQL用户名和密码连接到源,因此在源上必须有一个用户账户供副本使用。当您设置副本时,通过 CHANGE REPLICATION SOURCE TO 语句(从 MySQL 8.0.23 开始)或 CHANGE MASTER TO 语句(MySQL 8.0.23 之前),可以通过 SOURCE_USER | MASTER_USER 选项指定用户名。任何具有 REPLICATION SLAVE 权限的账户都可以用于此操作。您可以选择为每个副本创建不同的账户,也可以使用相同的账户连接到源。
虽然您不必专门为复制创建一个账户,但需要注意的是,复制用户名和密码以明文形式存储在副本的连接元数据存储库 mysql.slave_master_info 中(参见第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';
请参阅第15.7.1节,“账户管理语句”,获取有关操作用户账户的更多信息。
重要
要使用使用 caching_sha2_password 插件进行身份验证的用户账户连接到源,您必须按照第19.3.1节,“设置复制以使用加密连接”中描述的方式设置安全连接,或者启用未加密连接以支持使用 RSA 密钥对进行密码交换。caching_sha2_password 认证插件是从 MySQL 8.0 开始新创建用户的默认插件(详细信息请参阅第8.4.1.2节,“缓存 SHA-2 可插拔认证”)。如果您为复制创建或使用的用户账户(由 MASTER_USER 选项指定)使用此认证插件,并且没有使用安全连接,则必须启用基于 RSA 密钥对的密码交换才能成功连接。
12.3.10.4. 获取复制源的二进制日志坐标
要配置副本以在正确的位置开始复制过程,您需要记录源在其二进制日志中的当前坐标。
警告
这个过程使用 FLUSH TABLES WITH READ LOCK,它会阻塞 InnoDB 表的 COMMIT 操作。
如果您计划关闭源以创建数据快照,可以选择跳过此过程,而是将二进制日志索引文件的副本与数据快照一起存储。在这种情况下,源在重新启动时会创建一个新的二进制日志文件。因此,副本必须开始复制过程的源二进制日志坐标是新文件的起始位置,即在复制的二进制日志索引文件中列出的文件后面的源上的下一个二进制日志文件。
要获取源的二进制日志坐标,请按照以下步骤进行:
通过命令行客户端连接到源,启动一个会话,并执行 FLUSH TABLES WITH READ LOCK 语句来刷新所有表并阻止写入操作:
mysql> FLUSH TABLES WITH READ LOCK;
警告
保持执行 FLUSH TABLES 语句的客户端会话保持运行状态,以保持读取锁生效。如果退出客户端,锁将被释放。
在源上的另一个会话中,使用 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 STATUS 或 mysqldump –master-data 显示的日志文件名和位置值为空。在这种情况下,当指定源的二进制日志文件和位置时,您需要使用的值是空字符串 (‘’) 和 4。
现在您已经获得了启用副本从源的二进制日志正确位置开始读取的信息。
接下来的步骤取决于您是否在源上有现有数据。请选择以下其中一种选项:
如果您有现有数据需要在开始复制之前与副本进行同步,请保持客户端运行以保持锁定状态。这样可以防止进行任何进一步的更改,以便复制到副本的数据与源保持同步。然后继续查看第19.1.2.5节,“选择数据快照方法”。
如果您正在设置新的源和副本组合,您可以退出第一个会话以释放读取锁定。请参阅第19.1.2.6.1节,“设置新源和副本的复制”来了解如何继续操作。
12.3.10.5. 选择数据快照的方法
如果源数据库包含现有数据,需要将这些数据复制到每个副本。有不同的方法可以从源数据库导出数据。以下各节描述了可能的选项。
为了选择适合的数据库导出方法,请在以下选项之间进行选择:
使用 mysqldump 工具创建您希望复制的所有数据库的导出文件。这是推荐的方法,特别是在使用 InnoDB 存储引擎时。
如果您的数据库存储在二进制可移植文件中,您可以将原始数据文件复制到副本。这可能比在每个副本上使用 mysqldump 导出并导入文件更有效,因为它跳过了在重放 INSERT 语句时更新索引的开销。但对于像 InnoDB 这样的存储引擎,这不是推荐的方法。
使用 MySQL Server 的克隆插件将所有数据从现有副本传输到克隆。有关使用此方法的说明,请参阅第7.6.7.7节,“复制的克隆”。
小技巧
要部署多个 MySQL 实例,您可以使用 InnoDB Cluster,它使您能够在 MySQL Shell 中轻松管理一组 MySQL 服务器实例。InnoDB Cluster 在一个可编程的环境中包装了 MySQL Group Replication,使您可以轻松地部署一个 MySQL 实例集群以实现高可用性。此外,InnoDB Cluster 与 MySQL Router 无缝接口,使您的应用程序可以连接到集群,而无需编写自己的故障转移过程。然而,对于不需要高可用性的类似用例,您可以使用 InnoDB ReplicaSet。MySQL Shell 的安装说明可以在这里找到。
12.3.10.5.1. 使用mysqldump创建数据快照
要创建现有源数据库中数据的快照,请使用 mysqldump 工具。完成数据导出后,在启动复制过程之前将这些数据导入副本。
以下示例将所有数据库导出到名为 dbdump.db 的文件中,并包括 –master-data 选项,该选项会自动附加所需的 CHANGE REPLICATION SOURCE TO 或 CHANGE MASTER TO 语句到副本上以开始复制过程:
$> mysqldump --all-databases --master-data > dbdump.db
备注
如果不使用 –master-data 选项,则需要在单独的会话中手动锁定所有表。请参阅第19.1.2.4节,“获取复制源的二进制日志坐标”。
可以使用 mysqldump 工具排除某些数据库的导出。如果您想要选择包含在导出中的数据库,请不要使用 –all-databases。选择以下其中一种选项:
使用 –ignore-table 选项排除数据库中的所有表。
使用 –databases 选项仅列出您要导出的数据库名称。
备注
默认情况下,如果源使用了 GTID(gtid_mode=ON),mysqldump 在导出中包含源上 gtid_executed 集中的 GTID,以将它们添加到副本上的 gtid_purged 集中。如果您仅导出特定的数据库或表,请注意 mysqldump 包含的值包括源上 gtid_executed 集中所有事务的 GTID,甚至包括已更改的数据库部分或服务器上未包含在部分导出中的其他数据库的事务。查看 mysqldump 的 –set-gtid-purged 选项的描述,以了解您使用的 MySQL Server 版本的默认行为结果,以及如何更改该行为,如果这种结果不适合您的情况。
更多信息,请参阅第6.5.4节,“mysqldump — 数据库备份程序”。
要导入数据,可以将导出的文件复制到副本,或者在远程连接到副本时从源访问该文件。
12.3.10.5.2. 使用原始数据文件创建数据快照
这部分描述了如何使用组成数据库的原始文件创建数据快照。使用存储引擎具有复杂缓存或日志算法的表时,需要额外的步骤来生成完全的“时间点”快照:即使已获取全局读锁定,初始复制命令可能会遗漏缓存信息和日志更新。存储引擎对此的响应取决于其崩溃恢复能力。
如果使用 InnoDB 表,您可以使用 MySQL Enterprise Backup 组件中的 mysqlbackup 命令来生成一致的快照。该命令记录了与快照对应的日志名称和偏移量,用于在副本上使用。MySQL Enterprise Backup 是商业产品,包含在 MySQL Enterprise 订阅的一部分中。详细信息请参阅第32.1节,“MySQL Enterprise Backup 概述”。
如果源和副本的 ft_stopword_file、ft_min_word_len 或 ft_max_word_len 的值不同,并且要复制具有全文索引的表,则此方法也不可靠。
假设上述异常不适用于您的数据库,请使用冷备份技术来获取 InnoDB 表的可靠二进制快照:首先缓慢关闭 MySQL Server,然后手动复制数据文件。
如果您的 MySQL 数据文件位于单个文件系统上,可以使用标准的文件复制工具如 cp 或 copy,远程复制工具如 scp 或 rsync,归档工具如 zip 或 tar,或文件系统快照工具如 dump 来创建 MyISAM 表的原始数据快照。如果只复制特定的数据库,则只复制与这些表相关的文件。对于 InnoDB,除非启用了 innodb_file_per_table 选项,否则所有数据库中的所有表都存储在系统表空间文件中。
以下文件不需要用于复制:
与 mysql 数据库相关的文件。
副本的连接元数据存储库文件 master.info(如果使用的话;现在已不建议使用该文件,请参阅第19.2.4节,“中继日志和复制元数据存储库”)。
源的二进制日志文件,但如果要使用此文件来定位副本的源二进制日志坐标,则需要保留二进制日志索引文件。
任何中继日志文件。
根据是否使用 InnoDB 表,选择以下其中一种方法:
如果使用 InnoDB 表,并且希望通过原始数据快照获得最一致的结果,请在过程中关闭源服务器:
获取读锁并获取源的状态。请参阅第19.1.2.4节,“获取复制源的二进制日志坐标”。
在单独的会话中关闭源服务器:
$> mysqladmin shutdown
复制 MySQL 数据文件。以下示例展示了常见的操作方式,您只需选择其中一种:
$> tar cf /tmp/db.tar ./data $> zip -r /tmp/db.zip ./data $> rsync --recursive ./data /tmp/dbdata
重启源服务器
如果您不使用 InnoDB 表,可以按照以下步骤在不关闭服务器的情况下从源获取系统快照:
获取读锁并获取源的状态。请参阅第19.1.2.4节,“获取复制源的二进制日志坐标”。
复制 MySQL 数据文件。以下示例展示了常见的操作方式,您只需选择其中一种:
$> tar cf /tmp/db.tar ./data $> zip -r /tmp/db.zip ./data $> rsync --recursive ./data /tmp/dbdata
在获取读锁的客户端中释放锁定:
mysql> UNLOCK TABLES;
创建数据库的归档或复制文件后,在启动复制过程之前将文件复制到每个副本。
12.3.10.6. 设置副本
以下部分描述如何设置副本。在继续之前,请确保您已经完成以下步骤:
配置源数据库的必要配置属性。参见第19.1.2.1节,“设置复制源配置”。
获取源数据库的状态信息,或者在关闭期间创建源数据库的二进制日志索引文件的数据快照副本。参见第19.1.2.4节,“获取复制源的二进制日志坐标”。
在源数据库上释放读锁:
mysql> UNLOCK TABLES;
在副本数据库上编辑MySQL配置。参见第19.1.2.2节,“设置副本配置”。
接下来的步骤取决于您是否有现有数据需要导入到副本数据库中。更多信息请参见第19.1.2.5节,“选择数据快照方法”。选择以下其中一种:
如果没有要导入的数据库快照,请参见第19.1.2.6.1节,“使用新源和副本设置复制”。
如果有要导入的数据库快照,请参见第19.1.2.6.2节,“使用现有数据设置复制”。
12.3.10.6.1. 使用新的源和副本设置复制
如果没有先前数据库的快照可供导入,配置副本以从新源开始复制。
要在源和新副本之间设置复制:
启动副本。
在副本上执行CHANGE REPLICATION SOURCE TO或CHANGE MASTER TO语句,设置源的配置。详见第19.1.2.7节,“在副本上设置源配置”。
在每个副本上执行这些副本设置步骤。
如果您正在设置新服务器,并且有来自不同服务器的现有数据库的转储,希望将其加载到复制配置中,也可以使用这种方法。通过将数据加载到新源中,数据会自动复制到副本中。
如果您正在使用来自不同现有数据库服务器的数据来创建新源来设置新的复制环境,请在新源上运行从该服务器生成的转储文件。数据库更新会自动传播到副本中:
$> mysql -h source < fulldb.dump
12.3.10.6.2. 使用现有数据设置复制
在使用现有数据设置复制时,在开始复制之前,将快照从源传输到副本。将数据导入副本的过程取决于您在源上如何创建数据快照。
小技巧
要部署多个 MySQL 实例,您可以使用 InnoDB Cluster,它能够在 MySQL Shell 中轻松管理一组 MySQL 服务器实例。InnoDB Cluster 将 MySQL Group Replication 封装在一个编程环境中,使您能够轻松部署一个 MySQL 实例集群以实现高可用性。此外,InnoDB Cluster 与 MySQL Router 紧密集成,使您的应用能够连接到集群,无需编写自己的故障切换过程。然而,对于不需要高可用性的类似用例,您可以使用 InnoDB ReplicaSet。MySQL Shell 的安装说明可以在这里找到。
备注
如果要复制的复制源服务器或现有副本在创建新副本时具有任何计划事件,请确保在启动新副本之前在新副本上将这些事件禁用。如果新副本上运行了已经在源上运行过的事件,则重复的操作会导致错误。事件调度器由 event_scheduler 系统变量控制,默认情况下从 MySQL 8.0 开始为 ON,因此原始服务器上活动的事件在新副本启动时默认会运行。要停止新副本上所有事件的运行,可以在新副本上将 event_scheduler 系统变量设置为 OFF 或 DISABLED。或者,您可以使用 ALTER EVENT 语句将各个事件设置为 DISABLE 或 DISABLE ON SLAVE,以防止它们在新副本上运行。您可以使用 SHOW 语句或信息模式中的 EVENTS 表列出服务器上的事件。有关更多信息,请参见第19.5.1.16节,“调用特性的复制”。
作为创建新副本的替代方法,MySQL Server 的克隆插件可以用于将现有副本的所有数据和复制设置转移到克隆副本中。有关使用此方法的详细说明,请参阅第7.6.7.7节,“用于复制的克隆”。
作为创建新副本的替代方法,MySQL Server 的克隆插件可以用于将现有副本的所有数据和复制设置转移到克隆副本中。有关使用此方法的详细说明,请参阅第7.6.7.7节,“用于复制的克隆”。
按照以下步骤设置使用现有数据的复制:
如果您使用了MySQL Server的克隆插件从现有副本创建了克隆(参见第7.6.7.7节,“用于复制的克隆”),数据已经传输完毕。否则,可以使用以下方法之一将数据导入副本。
如果使用了 mysqldump,启动副本服务器时确保不启动复制,可以使用 –skip-slave-start 选项(或从 MySQL 8.0.24 开始使用 skip_slave_start 系统变量)。然后导入转储文件:
$> mysql < fulldb.dump
如果使用了原始数据文件创建快照,将数据文件解压到副本的数据目录中。例如:
$> tar xvf dbdump.tar
您可能需要设置文件的权限和所有权,以便副本服务器能够访问和修改它们。然后通过使用 –skip-slave-start 选项(或从 MySQL 8.0.24 开始使用 skip_slave_start 系统变量)启动副本服务器。
使用来自源的复制坐标配置副本。这告诉副本复制需要从源的二进制日志文件的哪个位置开始。还要使用源的登录凭据和主机名配置副本。有关所需的 CHANGE REPLICATION SOURCE TO 或 CHANGE MASTER TO 语句的更多信息,请参见第19.1.2.7节,“在副本上设置源配置”。
通过发出 START REPLICA(或在 MySQL 8.0.22 之前的版本中,START SLAVE)语句启动复制线程。
执行完这些步骤后,副本将连接到源,并复制自快照以来在源上发生的任何更新。如果由于任何原因副本无法复制,错误消息将会记录在副本的错误日志中。
副本使用其连接元数据存储库和应用程序元数据存储库中记录的信息来跟踪它已处理源的二进制日志的多少。从 MySQL 8.0 开始,默认情况下,这些存储库是名为 mysql 数据库中的 slave_master_info 和 slave_relay_log_info 表。除非您完全了解其影响,并且知道自己在做什么,否则不要删除或编辑这些表。即使在这种情况下,最好使用 CHANGE REPLICATION SOURCE TO 或 CHANGE MASTER TO 语句来更改复制参数。副本将使用语句中指定的值自动更新复制元数据存储库。有关更多信息,请参见第19.2.4节,“中继日志和复制元数据存储库”。
备注
副本的连接元数据存储库中的内容会覆盖命令行或 my.cnf 文件中指定的某些服务器选项。更多详细信息请参见第19.1.6节,“复制和二进制日志选项和变量”。
源的单个快照足以用于多个副本。要设置额外的副本,请使用相同的源快照,并按照刚刚描述的副本部分的步骤操作。
12.3.10.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_PATH 或 GET_SOURCE_PUBLIC_KEY | GET_MASTER_PUBLIC_KEY 选项,以启用基于 RSA 密钥对的密码交换。
12.3.10.8. 向复制环境添加副本
您可以在不停止源服务器的情况下向现有的复制配置中添加另一个副本。为此,可以通过复制现有副本的数据目录来设置新副本,并为新副本指定不同的服务器 ID(由用户指定)和服务器 UUID(在启动时生成)。
备注
如果您要复制的复制源服务器或现有副本用于创建新副本的服务器有任何计划事件,请确保在启动新副本之前在新副本上禁用这些事件。如果新副本上运行了已在源上运行过的事件,会导致重复操作引发错误。事件调度器由 event_scheduler 系统变量控制,默认情况下从 MySQL 8.0 开始为 ON,因此原始服务器上活动的事件在新副本启动时默认会运行。要停止新副本上所有事件的运行,可以在新副本上将 event_scheduler 系统变量设置为 OFF 或 DISABLED。或者,您可以使用 ALTER EVENT 语句将各个事件设置为 DISABLE 或 DISABLE ON SLAVE,以防止它们在新副本上运行。您可以使用 SHOW 语句或信息模式中的 EVENTS 表列出服务器上的事件。有关更多信息,请参见第19.5.1.16节,“调用特性的复制”。
作为在这种方式外创建新副本的替代方法,可以使用 MySQL Server 的克隆插件将所有数据和复制设置从现有副本传输到一个克隆副本。有关使用此方法的说明,请参见第7.6.7.7节,“用于复制的克隆”。
要复制现有副本而不进行克隆,请按照以下步骤操作:
停止现有副本,并记录副本状态信息,特别是源二进制日志文件和中继日志文件的位置。您可以通过性能模式中的复制表(参见第29.12.11节,“性能模式复制表”)或执行 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
Shut down the existing replica:
$> mysqladmin shutdown
将现有副本的数据目录复制到新副本,包括日志文件和中继日志文件。您可以通过使用 tar 或 WinZip 创建存档,或者使用 cp 或 rsync 等工具进行直接复制来完成此操作。
重要
在复制之前,请验证现有副本所有相关文件实际上存储在数据目录中。例如,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。
另外,如果在遵循本节其余步骤后尝试启动新副本时遇到了类似之前描述的错误,请执行以下步骤:
如果尚未这样做,请在新副本上执行 STOP REPLICA。 如果已经重新启动了现有副本,请在现有副本上执行 STOP REPLICA。
将现有副本的中继日志索引文件内容复制到新副本的中继日志索引文件中,并确保覆盖文件中的任何内容。
继续执行本节中的其余步骤。
复制完成后,重新启动现有副本。
在新副本上编辑配置,并为新副本分配一个不与源或任何现有副本重复的唯一服务器 ID(使用 server_id 系统变量)。
启动新副本服务器,确保尚未启动复制,可以通过指定 –skip-slave-start 选项,或从 MySQL 8.0.24 开始使用 skip_slave_start 系统变量。使用性能模式中的复制表或执行 SHOW REPLICA STATUS 来确认新副本与现有副本相比具有正确的设置。还显示服务器 ID 和服务器 UUID,并验证这些值对于新副本来说是正确且唯一的。
通过执行 START REPLICA 语句启动副本线程。现在,新副本将使用其连接元数据存储库中的信息启动复制过程。
12.3.10.9. 例子
12.3.10.9.1. 主节点配置
sudo apt update
sudo apt install mysql-server
vim /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 10.196.126.10
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
sudo systemctl restart mysql
sudo mysql
CREATE USER 'repl'@'10.196.126.11' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.196.126.11';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
12.3.10.9.2. 从节点
sudo apt update
sudo apt install mysql-server
vim /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 10.196.126.11
server-id = 2
sudo systemctl restart mysql
sudo mysql
CHANGE MASTER TO
MASTER_HOST = '10.196.126.10',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'password',
MASTER_LOG_FILE = 'mysql-bin.000002', # 要改成主节点的LOG文件的名称
MASTER_LOG_POS = 157; # 要改成主节点LOG文件的POS
START SLAVE;
SHOW SLAVE STATUS \G;
重要
确保 Slave_IO_Running 和 Slave_SQL_Running 都为 Yes,表明复制已经正常工作。
12.3.10.9.3. FAQ
我看到Last_IO_Error提示:Error connecting to source ‘repl@10.196.126.10:3306’. This was attempt 5/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin ‘caching_sha2_password’ reported error: Authentication requires secure connection.
问题出在 MySQL 的认证插件 caching_sha2_password 上,它要求使用安全连接进行认证,而当前连接可能不是安全连接导致认证失败。解决这个问题可以通过以下几个步骤来尝试:
主节点修改下密码插件
ALTER USER 'repl'@'10.196.126.11' IDENTIFIED WITH mysql_native_password BY 'password';
重启:
sudo systemctl restart mysql
从节点重新修改下:
CHANGE MASTER TO
MASTER_HOST = '10.196.126.10',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'password',
MASTER_LOG_FILE = 'mysql-bin.000002', # 要改成主节点的LOG文件的名称
MASTER_LOG_POS = 157; # 要改成主节点LOG文件的POS
START SLAVE;
SHOW SLAVE STATUS;