简介
MySQL 8.0.17中引入的克隆插件允许在本地或从远程 MySQL 服务器实例克隆数据。克隆数据是存储在 InnoDB 中的数据的物理快照,其中包括模式、表、表空间和数据字典元数据。克隆数据包含一个功能齐全的数据目录,该目录允许使用克隆插件进行 MySQL 服务器配置。
本地克隆
本地克隆操作将数据从启动克隆操作的 MySQL 服务器实例克隆到运行 MySQL 服务器实例的同一服务器或节点上的目录。
远程克隆
远程克隆操作涉及启动克隆操作的本地 MySQL 服务器实例(“接收者”)和源数据所在的远程 MySQL 服务器实例(“捐赠者”)。当对收件人启动远程克隆操作时,克隆数据通过网络从捐助者传输到收件人。默认情况下,远程克隆操作在从捐献者克隆数据之前,从接收者数据目录中删除现有的用户创建的数据(模式、表、表空间)和二进制日志。还可以选择将数据克隆到收件人的另一个目录,以避免从当前收件人数据目录中删除数据。
安装克隆插件
启动时在配置文件中配置
[mysqld]
plugin-load-add=mysql_clone.so
运行时加载
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
安装验证
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME = 'clone';
+------------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+------------------------+---------------+
| clone | ACTIVE |
+------------------------+---------------+
如果插件以前已经在 INSTALL PLUGIN 中注册过,或者加载了—— PLUGIN-load-add,那么您可以在服务器启动时使用—— clone 选项来控制插件的激活状态。例如,要在启动时加载插件并防止它在运行时被删除,请使用以下选项:
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT
克隆本地数据
执行 CLONE LOCAL DATA DIRECTORY 语句需要 BACKUP _ ADMIN 特权。
mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user';
本地克隆
mysql> CLONE LOCAL DATA DIRECTORY = '/path/to/clone_dir';
-- 示例
CLONE LOCAL DATA DIRECTORY = '/db_data/mysql/clone';
目录clone必须不存在。
克隆远程数据
克隆插件支持以下语法来克隆远程数据: 即从远程 MySQL 服务器实例(捐助者)克隆数据,并将其传输到启动克隆操作的 MySQL 实例(接收者)。
CLONE INSTANCE FROM 'user'@'host':port
IDENTIFIED BY 'password'
[DATA DIRECTORY [=] 'clone_dir']
[REQUIRE [NO] SSL];
注意事项
- 在捐赠者上,克隆用户需要 BACKUP _ ADMIN 特权来访问和传输来自捐赠者的数据,并在克隆操作期间阻塞并发 DDL。在 MySQL 8.0.27之前,在捐助者上阻塞了克隆操作期间的并发 DDL。默认情况下,在 MySQL 8.0.27中,捐赠者上允许并发 DDL。参见5.6.7.4节“克隆和并发 DDL”。
- 在收件人上,克隆用户需要 CLONE _ ADMIN 特权来替换收件人数据,在克隆操作期间阻塞收件人的 DDL,并自动重新启动服务器。CLONE _ ADMIN 特权隐式地包括 BACKUP _ ADMIN 和 SHUTDOWN 特权。
- MYSQL 8.0.17及更高版本支持克隆插件。捐赠者和接收者必须是相同的 MySQL 服务器版本和版本。要确定 MySQL 服务器版本和版本,请发出以下查询:
- 捐赠者和接收者的 MySQL 服务器实例必须在相同的操作系统和平台上运行。
- 收件人必须有足够的磁盘空间来存放克隆的数据。默认情况下,用户创建的数据(模式、表、表空间)和二进制日志在克隆捐赠者数据之前在接收者上被删除,因此您只需要足够的空间来存放捐赠者数据。如果使用 DATA DIRECTORY 子句克隆到指定目录,则必须有足够的磁盘空间来存放现有的收件人数据和克隆的数据。通过检查文件系统上的数据目录大小和驻留在数据目录之外的任何表空间的大小,可以估计数据的大小。在估计捐赠者的数据大小时,请记住只克隆 InnoDB 数据。如果在其他存储引擎中存储数据,则相应地调整数据大小估计值。
- InnoDB 允许在 data 目录之外创建一些表空间类型。如果捐助者 MySQL 服务器实例的表空间位于数据目录之外,那么克隆操作必须能够访问这些表空间。可以查询 InformationSchemaFILES 表来标识驻留在数据目录之外的表空间。驻留在数据目录之外的文件具有指向数据目录以外目录的完全限定路径。
mysql> SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES;
- 对捐赠者激活的插件,包括任何 keyring 插件,也必须对接收者激活。可以通过发出 SHOW PLUGINS 语句或查询 Information Schema PLUGINS 表来识别活动插件。
- 捐赠者和接收者必须具有相同的 MySQL 服务器字符集和排序规则。有关 MySQL 服务器字符集和排序规则配置的信息,请参见第10.15节“字符集配置”。
- 捐赠者和接收者需要相同的 inodb _ page _ size 和 inodb _ data _ file _ path 设置。捐赠者和收件者的 inodb _ data _ file _ path 设置必须指定相同数量的等效大小的数据文件。可以使用 SHOW VARIABLES 语法检查变量设置。
mysql> SHOW VARIABLES LIKE 'innodb_page_size';
mysql> SHOW VARIABLES LIKE 'innodb_data_file_path';
- 如果克隆加密或页压缩的数据,则捐助方和接收方的文件系统块大小必须相同。对于页压缩数据,收件人文件系统必须支持稀疏文件和打孔,以便在收件人上发生打孔。有关这些特性以及如何识别使用它们的表和表空间的信息,请参阅第5.6.7.5节“克隆加密数据”和第5.6.7.6节“克隆压缩数据”。要确定文件系统块的大小,请参考操作系统文档。
- 收件人的 clone _ valid_ donor _ list 设置必须包含捐助者 MySQL 服务器实例的主机地址。您只能从有效捐赠者列表中的主机克隆数据。配置此变量需要具有 SYSTEM _ VARIABLES _ ADMIN 特权的 MySQL 用户。在本节后面的远程克隆示例中提供了设置 clone _ valid_ donallist 变量的说明。您可以使用 SHOW VARIABLES 语法检查 clon- 有效-捐赠者-列表设置。
mysql> SHOW VARIABLES LIKE 'clone_valid_donor_list';
- 必须没有其他正在运行的克隆操作。一次只允许执行一个克隆操作。若要确定是否正在运行克隆操作,请查询 clone _ status 表。请参见使用性能架构克隆表监视克隆操作。
- 克隆插件以1MB 的包和元数据的形式传输数据。因此,捐赠者和接收者 MySQL 服务器实例上所需的最小 max _ allow _ pack 值为2MB。Max _ allow _ pack 值小于2MB 将导致错误。使用以下查询来检查 max _ allow _ pack 设置:
mysql> SHOW VARIABLES LIKE 'max_allowed_packet';
参考:dev.mysql.com/doc/refman/…
远程克隆示例
下面的示例演示如何克隆远程数据。默认情况下,远程克隆操作会删除收件人上用户创建的数据(模式、表、表空间)和二进制日志,将新数据克隆到收件人数据目录,然后重新启动 MySQL 服务器。
mysql> CREATE USER 'donor_clone_user'@'example.donor.host.com' IDENTIFIED BY 'password';
mysql> GRANT BACKUP_ADMIN on *.* to 'donor_clone_user'@'example.donor.host.com';
-- 示例
CREATE USER 'donor_clone_user'@'%' IDENTIFIED BY 'Qwer1234';
GRANT BACKUP_ADMIN on *.* to 'donor_clone_user'@'%';
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
mysql> CREATE USER 'recipient_clone_user'@'example.recipient.host.com' IDENTIFIED BY 'password';
mysql> GRANT CLONE_ADMIN on *.* to 'recipient_clone_user'@'example.recipient.host.com';
-- 示例
CREATE USER 'recipient_clone_user'@'%' IDENTIFIED BY 'Qwer1234';
GRANT CLONE_ADMIN on *.* to 'recipient_clone_user'@'%';
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
mysql> SET GLOBAL clone_valid_donor_list = 'example.donor.host.com:3306';
-- 示例
SET GLOBAL clone_valid_donor_list = '10.5.54.3:3306';
mysql> CLONE INSTANCE FROM 'donor_clone_user'@'example.donor.host.com':3306
IDENTIFIED BY 'password';
-- 示例
SET GLOBAL clone_valid_donor_list = '10.5.54.3:3306';
CLONE INSTANCE FROM 'donor_clone_user'@'10.5.54.3':3306 IDENTIFIED BY 'Qwer1234';
数据克隆后,收件人上的 MySQL 服务器实例将自动重新启动。
克隆到命名目录
语句如下
mysql> CLONE INSTANCE FROM 'user'@'example.donor.host.com':3306
IDENTIFIED BY 'password'
DATA DIRECTORY = '/path/to/clone_dir';
-- 示例
CLONE INSTANCE FROM 'donor_clone_user'@'10.5.54.3':3306
IDENTIFIED BY 'Qwer1234'
DATA DIRECTORY = '/db_data/clone';
当克隆到命名目录时,在克隆数据之后,不会自动重新启动收件人 MySQL 服务器实例。如果要在指定的目录上重新启动 MySQL 服务器,必须手动这样做:
$> mysqld_safe --datadir=/path/to/clone_dir
克隆和并发 DDL
在 MySQL 8.0.27之前,在克隆操作期间不允许对捐赠者和接收者 MySQL Server 实例(包括 TRUNCATE TABLE)进行 DDL 操作。在选择数据源时应该考虑这个限制。一种解决方案是使用专用的捐助者实例,它可以适应在克隆数据时被阻塞的 DDL 操作。
为了防止在克隆操作期间发生并发 DDL,需要在捐赠者和接收者上获得一个独占备份锁。克隆 _ ddl _ timeout 变量定义克隆操作等待备份锁的时间(以秒为单位)。默认设置为300秒。如果没有在指定的时间限制下获得备份锁,则克隆操作将失败并出现错误。
默认情况下,在 MySQL 8.0.27中,捐赠者上允许并发 DDL。捐助者上的并发 DDL 支持由 clone _ block _ DDL 变量控制。可以使用 SET 语句动态地启用和禁用并发 DDL 支持。
SET GLOBAL clone_block_ddl={OFF|ON}
默认设置是 clone _ block _ DDL = OFF,它允许在捐赠者上并发 DDL。
是否克隆并发 DDL 操作的效果取决于在克隆操作获取动态快照之前 DDL 操作是否完成。
在克隆操作期间不允许执行的 DDL 操作,无论 clone _ block _ DDL 设置如何,包括:
- ALTER TABLE tbl_name DISCARD TABLESPACE;
- ALTER TABLE tbl_name IMPORT TABLESPACE;
- ALTER INSTANCE DISABLE INNODB REDO_LOG;
加密传输
压缩传输
复制克隆
克隆插件支持复制。除了克隆数据之外,克隆操作还从提供者提取复制坐标并将它们传输给接收者,这样就可以使用克隆插件来配置 Group Replication 成员和副本。使用克隆插件进行配置要比复制大量事务快得多,效率也高得多。
在克隆的 MySQL 服务器实例上发出此查询,以检查传输给收件人的二进制日志位置:
mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
在一个克隆的 MySQL 服务器实例上发出这个查询,以检查传输给收件人的 GTID _ execute GTID 集:
mysql> SELECT @@GLOBAL.GTID_EXECUTED;
请注意,如果在服务器上使用设置 master _ info _ itory = FILE 和 Relit _ log _ info _ itory = FILE (这在 MySQL 8.0中不是默认设置,并且不推荐使用) ,则不会克隆复制元数据存储库; 只有在设置了 TABLE 的情况下才会克隆它们。
基于GTID的复制
mysql> CHANGE MASTER TO MASTER_HOST = 'source_host_name', MASTER_PORT = source_port_num,
...
MASTER_AUTO_POSITION = 1,
FOR CHANNEL 'setup_channel';
mysql> START SLAVE USER = 'user_name' PASSWORD = 'password' FOR CHANNEL 'setup_channel';
Or from MySQL 8.0.22 and 8.0.23:
mysql> CHANGE SOURCE TO SOURCE_HOST = 'source_host_name', SOURCE_PORT = source_port_num,
...
SOURCE_AUTO_POSITION = 1,
FOR CHANNEL 'setup_channel';
mysql> START REPLICA USER = 'user_name' PASSWORD = 'password' FOR CHANNEL 'setup_channel';
-- 示例
CHANGE MASTER TO MASTER_HOST = '10.5.54.3', MASTER_PORT = 3306,MASTER_USER='admin',MASTER_PASSWORD='Qwer1234',
MASTER_AUTO_POSITION = 1;
START SLAVE;
SHOW SLAVE STATUS G
基于pos与日志名的复制
mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
mysql> CHANGE MASTER TO MASTER_HOST = 'source_host_name', MASTER_PORT = source_port_num,
...
MASTER_LOG_FILE = 'source_log_name',
MASTER_LOG_POS = source_log_pos,
FOR CHANNEL 'setup_channel';
mysql> START SLAVE USER = 'user_name' PASSWORD = 'password' FOR CHANNEL 'setup_channel';
Or from MySQL 8.0.22 and 8.0.23:
mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
mysql> CHANGE SOURCE TO SOURCE_HOST = 'source_host_name', SOURCE_PORT = source_port_num,
...
SOURCE_LOG_FILE = 'source_log_name',
SOURCE_LOG_POS = source_log_pos,
FOR CHANNEL 'setup_channel';
mysql> START REPLICA USER = 'user_name' PASSWORD = 'password' FOR CHANNEL 'setup_channel';
监控克隆操作
使用性能模式克隆表监控克隆操作
Clone_status 表提供当前或上一次执行的克隆操作的状态。克隆操作有四种可能的状态: 未启动、正在进行、已完成和失败。
Clone_Progress 表按阶段为当前或上一次执行的克隆操作提供进度信息。克隆操作的阶段包括 DROP DATA、 FILE COPY、 PAGE _ COPY、 REDO _ COPY、 FILE _ SYNC、 RESTART 和 RECOVERY。
mysql> select * from performance_schema.Clone_status;
mysql> select * FROM performance_schema.clone_progress;
dev.mysql.com/doc/refman/…
使用性能模式阶段事件监视克隆操作
克隆操作阶段事件的发生顺序包括:
- stage/innodb/clone (file copy):指示克隆操作的文件复制阶段的进度。WORK _ ESTIMATION 和 WORK _ COMPLETED 单元是文件块。要传输的文件数量在文件复制阶段开始时就已知,并且根据文件数量估计块的数量。WORK _ ESTIMATE 被设置为估计的文件块数。WORK _ COMPLETED 在每个块发送后更新。
- stage/innodb/clone (page copy):指示克隆操作的页面复制阶段的进度。WORK _ ESTIMated 和 WORK _ COMPLETED 单元是页面。一旦文件复制阶段完成,将要传输的页数就已知,并且 WORK _ ESTIMATE 被设置为此值。WORK _ COMPLETED 在每个页面发送后更新。
- stage/innodb/clone (redo copy): 指示克隆操作的重做复制阶段的进度。WORK _ ESTIMated 和 WORK _ COMPLETED 单元是重做块。一旦页面复制阶段完成,将要传输的重做块的数量就是已知的,WORK _ ESTIMATION 被设置为这个值。WORK _ COMPLETED 在每个块发送后更新。
示例
mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES'
WHERE NAME LIKE 'stage/innodb/clone%';
mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'
WHERE NAME LIKE '%stages%';
mysql> SET GLOBAL clone_valid_donor_list = '10.5.54.3:3306';
mysql> CLONE LOCAL DATA DIRECTORY = '/path/to/cloned_dir';
-- 示例
SET GLOBAL clone_valid_donor_list = '10.5.54.3:3306';
! rm -rf /db_data/mysql/clone
CLONE LOCAL DATA DIRECTORY = '/db_data/mysql/clone';
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current
WHERE EVENT_NAME LIKE 'stage/innodb/clone%';
+--------------------------------+----------------+----------------+
| EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED |
+--------------------------------+----------------+----------------+
| stage/innodb/clone (redo copy) | 1 | 1 |
+--------------------------------+----------------+----------------+
如果克隆操作已经完成,events _ stage _ current 表将返回一个空集。在这种情况下,可以检查 events _ stage _ history 表来查看已完成操作的事件数据。例如:
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_history
WHERE EVENT_NAME LIKE 'stage/innodb/clone%';
+--------------------------------+----------------+----------------+
| EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED |
+--------------------------------+----------------+----------------+
| stage/innodb/clone (file copy) | 301 | 301 |
| stage/innodb/clone (page copy) | 0 | 0 |
| stage/innodb/clone (redo copy) | 1 | 1 |
+--------------------------------+----------------+----------------+
使用性能模式克隆工具监控克隆操作
Performance Schema 为克隆操作的高级性能监视提供了工具。查看可用的克隆工具,并发出以下查询:
mysql> SELECT NAME,ENABLED FROM performance_schema.setup_instruments
WHERE NAME LIKE '%clone%';
+---------------------------------------------------+---------+
| NAME | ENABLED |
+---------------------------------------------------+---------+
| wait/synch/mutex/innodb/clone_snapshot_mutex | NO |
| wait/synch/mutex/innodb/clone_sys_mutex | NO |
| wait/synch/mutex/innodb/clone_task_mutex | NO |
| wait/synch/mutex/group_rpl/LOCK_clone_donor_list | NO |
| wait/synch/mutex/group_rpl/LOCK_clone_handler_run | NO |
| wait/synch/mutex/group_rpl/LOCK_clone_query | NO |
| wait/synch/mutex/group_rpl/LOCK_clone_read_mode | NO |
| wait/synch/cond/group_rpl/COND_clone_handler_run | NO |
| wait/io/file/innodb/innodb_clone_file | YES |
| stage/innodb/clone (file copy) | YES |
| stage/innodb/clone (redo copy) | YES |
| stage/innodb/clone (page copy) | YES |
| statement/abstract/clone | YES |
| statement/clone/local | YES |
| statement/clone/client | YES |
| statement/clone/server | YES |
| memory/innodb/clone | YES |
| memory/clone/data | YES |
+---------------------------------------------------+---------+
性能模式等待工具跟踪需要时间的事件:
状态变量
show global status like '%clone%';
停止克隆操作
mysql> SELECT * FROM performance_schema.clone_statusG
*************************** 1. row ***************************
ID: 1
PID: 8
STATE: In Progress
BEGIN_TIME: 2019-07-15 11:58:36.767
END_TIME: NULL
SOURCE: LOCAL INSTANCE
DESTINATION: /path/to/clone_dir/
ERROR_NO: 0
ERROR_MESSAGE:
BINLOG_FILE:
BINLOG_POSITION: 0
GTID_EXECUTED:
mysql> kill 8
克隆变量
Name | Cmd-Line | Option File | System Var | Status Var | Var Scope | Dynamic |
---|---|---|---|---|---|---|
clone_autotune_concurrency | Yes | Yes | Yes | Global | Yes | |
clone_block_ddl | Yes | Yes | Yes | Global | Yes | |
clone_buffer_size | Yes | Yes | Yes | Global | Yes | |
clone_ddl_timeout | Yes | Yes | Yes | Global | Yes | |
clone_delay_after_data_drop | Yes | Yes | Yes | Global | Yes | |
clone_donor_timeout_after_network_failure | Yes | Yes | Yes | Global | Yes | |
clone_enable_compression | Yes | Yes | Yes | Global | Yes | |
clone_max_concurrency | Yes | Yes | Yes | Global | Yes | |
clone_max_data_bandwidth | Yes | Yes | Yes | Global | Yes | |
clone_max_network_bandwidth | Yes | Yes | Yes | Global | Yes | |
clone_ssl_ca | Yes | Yes | Yes | Global | Yes | |
clone_ssl_cert | Yes | Yes | Yes | Global | Yes | |
clone_ssl_key | Yes | Yes | Yes | Global | Yes | |
clone_valid_donor_list | Yes | Yes | Yes | Global | Yes |
克隆系统变量详解:dev.mysql.com/doc/refman/…
使用限制
- 在 MySQL 8.0.27之前,在克隆操作期间不允许在捐赠者和接收者(包括 TRUNCATE TABLE)上使用 DDL。在选择数据源时应该考虑这个限制。一种解决方案是使用专用的捐助者实例,它可以适应在克隆数据时被阻塞的 DDL 操作。允许并发 DML。
- 默认情况下,在 MySQL 8.0.27中,捐赠者上允许并发 DDL。对捐助者上的并发 DDL 的支持是由 clone _ block _ DDL 变量控制的。参见5.6.7.4节“克隆和并发 DDL”。
- 无法从不同的 MySQL 服务器版本或版本克隆实例。捐赠者和接收者必须具有完全相同的 MySQL 服务器版本和版本。例如,您不能在 MySQL 5.7和 MySQL 8.0之间,或者在 MySQL 8.0.19和 MySQL 8.0.20之间进行克隆。这个克隆插件只支持 MySQL 8.0.17及更高版本。
- 只有在 MySQL 8.0.26及更高版本中才支持从捐赠者 MySQL 服务器实例克隆到相同版本和版本的修复程序 MySQL 服务器实例。
- 一次只能克隆一个 MySQL 实例。不支持在单个克隆操作中克隆多个 MySQL 实例。
- 由 mysqlx _ port 指定的 X 协议端口不支持远程克隆操作(在 CLONE INSTANCE 语句中指定捐助者 MySQL 服务器实例的端口号时)。
- 克隆插件不支持克隆 MySQL 服务器配置。收件人 MySQL 服务器实例保留其配置,包括持久化系统变量设置(参见5.1.9.3节“持久化系统变量”)
- 克隆插件不支持二进制日志的克隆。
- 这个克隆插件只克隆存储在 InnoDB 中的数据。不克隆其他存储引擎数据。存储在任何模式(包括 sys 模式)中的 MyISAM 和 CSV 表被克隆为空表。
- 不支持通过 MySQL 路由器连接到捐助者的 MySQL 服务器实例。
- 本地克隆操作不支持用绝对路径创建的一般表空间的克隆。与源表空间文件具有相同路径的克隆表空间文件将导致冲突。
延伸思考
Clone使用场景是什么?
可否用来做备份?如果用来做备份,相比Xtrabackup优缺点是什么?
Clone 作为备份与 Xtrabackup 的区别是什么?
参考文献
zhuanlan.zhihu.com/p/433606318