最详细的clone plugin 介绍

一、能够实现的功能介绍

MySQL 8.0.17推出的clone plugin插件,利用克隆插件可以扩展实现:
SQL命令进行备份。
Slave节点快速搭建。
MGR节点快速扩充。

而克隆插件的基础功能,可以理解为:
可以对本身的实例的InnoDB数据,备份到本服务器的指定目录中。(本地克隆:本地备份)
可以将远程实例的InnoDB数据还原到当前的实例中。(远端克隆:远端备份 + 本实例自动还原)
可以将远程实例的InnoDB数据还原到当前的实例的其他目录中。(远端克隆:远端备份)

二、克隆插件介绍

克隆插件允许从本地或远程的MySQL Server中克隆数据。克隆的数据是存储在InnoDB中的schema(database)、table(表)、tablespaces(表空间)和data dictionary metadata(数据字典元数据)的物理快照。该物理快照实际上是一个功能完整的数据目录,MySQL克隆插件可以使用该数据目录来配置并恢复一个MySQL Server。

2.1克隆插件分为本地clone和远程clone:

本地克隆:指的是将数据从启动克隆操作的MySQL Server克隆到该MySQL Server的主机上的一个指定目录下
远程克隆:涉及到启动克隆操作的本地MySQL Server(称为"recipient",即,数据的接收者或接收方)和数据源所在的远程MySQL Server(称为"donor",即,数据的提供者或发送方),在接收方上启动远程克隆操作时,克隆的数据会通过网络从发送方传输到接收方。
默认情况下,远程可能那个操作会删除接收方数据目录中的所有数据,并将其替换为克隆的新数据。如果不希望接收方中的现有数据被删除,你也可以在接收方中执行克隆操作时将克隆数据指定存放在其他目录中

2.2克隆插件应用场景:

对于克隆的数据本身来说,本地克隆操作与远程克隆操作没有太大区别。
克隆插件支持在复制拓扑中使用。除了克隆数据外,克隆操作还能够从发送方中提取和传输复制座标(二进制日志的位置),并将其应用于接收方,也就是说,我们可以使用克隆插件来在组复制中添加新的组成员,也可以在主从复制拓扑中添加新的从库。
与通过二进制日志来复制大量事务相比,通过克隆插件要快得多,效率也更高(更多信息详见"6、在复制拓扑中使用克隆")。组复制成员还可以配置使用克隆插件来作为另一种恢复方法(如果不使用克隆插件,则必须使用基于二进制日志的状态传输进行数据恢复),当组成员和待加入组的Server都配置支持克隆插件时,待加入组的Server可以自行决定选择一个更加高效的方式从种子成员中获取数据。
有关更多信息,请参见《MySQL Group Replication for 8.0》."4.3.1 克隆用于分布式恢复"。

2.3克隆插件支持克隆数据加密的和数据页压缩:

克隆插件支持克隆数据加密的和数据页压缩。详情可参考"4、克隆加密数据"和“5、克隆压缩数据"

2.4使用克隆功能须先安装克隆插件:

有关安装的说明,详情可参考"三、安装克隆插件"。有关克隆的命令,详情可参考"四、克隆演示”。

三、安装克隆插件

下面是mysql8.0.20二进制安装和插件具体安装过程:


[root@mysql-redis182 3307]# wget -P /data/soft https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz
[root@mysql-redis182 3307]# tar Jxf /data/soft/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz -C /usr/local/
[root@mysql-redis182 logs]# cd /usr/local/;ln -sv mysql-8.0.20-linux-glibc2.12-x86_64 mysql
[root@mysql-redis182 ~]# grep -w '/data/mysql/3307' /data/mysql/3307/my8.cnf 
datadir = /data/mysql/3307/data
slow_query_log_file = /data/mysql/3307/logs/slow.log
log-error = /data/mysql/3307/logs/error.log
log-bin = /data/mysql/3307/binlog/mysql-bin
innodb_undo_directory = /data/mysql/3307/undolog

[root@mysql-redis182 logs]# /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/3307/my8.cnf --initialize
开启mysql_clone.so参数写入配置文件;
[root@mysql-redis182 mysql]# grep clone /data/mysql/my8.cnf 
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT        ##启动时加载插件并防止它在运行时被删除,

 获取到密码:
[root@mysql-redis182 logs]# grep -w 'root@localhost' error.log |awk '{print $NF}'
nbspMeu*K4g1
[root@mysql-redis182 3307]# /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/3307/my8.cnf &
[1] 12614
[root@mysql-redis182 3307]# ss -lntup|grep 3306
tcp    LISTEN     0      1024     :::3306                 :::*                   users:(("mysqld",pid=12614,fd=35))
tcp    LISTEN     0      70       :::33060                :::*                   users:(("mysqld",pid=12614,fd=31))

修改密码:
root@localhost [(none)]>alter user user() identified by 'rRt&8UiJpN3v7Cx'
root@localhost [(none)]>select version();
+-----------+
| version() |
+-----------+
| 8.0.20    |
+-----------+
1 row in set (0.00 sec)

开启clone插件:

root@localhost [(none)]>INSTALL PLUGIN clone SONAME 'mysql_clone.so';

INSTALL PLUGIN语句可以加载插件,并将其注册到mysql系统库下的mysql.plugins表中,这样在后续重启MySQL Server时不需要重复使用--plugin-load-add选项来加载插件库

验证插件是否安装完成,可以查看INFORMATION_SCHEMA.plugins表或者使用SHOW PLUGINS语句查看:

root@localhost [(none)]>SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone       | ACTIVE        |
+-------------+---------------+
1 row in set (0.00 sec)

卸载插件:UNINSTALL PLUGIN clone;

克隆插件参数写入配置文件:
例如,要在启动时加载插件并防止它在运行时被删除,可以使用以下选项:
提示在初始化mysql8.0 前不要加入下面的参数,否则导致初始化报错以及启动mysql报错
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT ##启动时加载插件并防止它在运行时被删除,

有关插件激活状态的更多信息,请参见链接https://dev.mysql.com/doc/refman/8.0/en/plugin-loading.html#server-plugin-activating

四、克隆插件演示:

4.1克隆本地数据:

克隆插件支持用于在本地克隆数据的语法,即,将数据从本地(相同主机)的一个MySQL Server的数据目录克隆到本地MySQL Server所在主机的一个指定目录下,
使用克隆插件执行克隆本地数据的操作语法如下:
mysql> CLONE LOCAL DATA DIRECTORY [=] 'clone_dir';

要正确使用CLONE语法,必须先安装克隆插件。有关安装说明,请参见"前文"。
执行CLONE LOCAL DATA DIRECTORY语句需要用户具有BACKUP_ADMIN权限,因此需要先授予操作用户该权限,语句如下:

#语法:
mysql> CLONE LOCAL DATA DIRECTORY = '/path/to/clone_dir';

其中,clone_user是用于执行克隆操作的MySQL用户。该用户可以是在"."上(全局权限)具有BACKUP_ADMIN权限的任何MySQL用户

mysql> GRANT BACKUP_ADMIN ON . TO 'clone_user'@'127.0.0.1' idnetified by 'sjdue2398uys'; 此语法在mysql8.0中不支持了

下面是正确的授权语法:

 create user clone_user@'127.0.0.1' identified by 'sjdue2398uys';flush privileges;
 GRANT BACKUP_ADMIN ON *.* TO clone_user@'127.0.0.1';
  grant all on *.* to clone_user@'127.0.0.1';
 [root@localhost mysql]# mysql -uclone_user -h127.0.0.1 -p'sjdue2398uys'
mysql> CLONE LOCAL DATA DIRECTORY = '/data/mysql/mydata_clone'; # 这是克隆的副本目录

Query OK, 0 rows affected (36.46 sec)

#查看克隆目录下的文件:

mysql>  system ls -lh /data/mysql/mydata_clone
总用量 5.1G
drwxr-x--- 2 mysql mysql 4.0K 5月   8 12:02 #clone
-rw-r----- 1 mysql mysql 5.6K 5月   8 12:01 ib_buffer_pool
-rw-r----- 1 mysql mysql 1.0G 5月   8 12:01 ibdata1
-rw-r----- 1 mysql mysql 2.0G 5月   8 12:02 ib_logfile0
-rw-r----- 1 mysql mysql 2.0G 5月   8 12:02 ib_logfile1
drwxr-x--- 2 mysql mysql 4.0K 5月   8 12:01 mysql
-rw-r----- 1 mysql mysql  24M 5月   8 12:01 mysql.ibd
drwxr-x--- 2 mysql mysql 4.0K 5月   8 12:01 sys
-rw-r----- 1 mysql mysql  10M 5月   8 12:01 undo_001
-rw-r----- 1 mysql mysql  10M 5月   8 12:01 undo_002

在上述操作语句中,"/path/to/clone_dir"是将数据克隆到本地目录的绝对路径。
该路径中,"clone_dir"目录不能事先存在(事先存在会报错),但路径前缀"/path/to/"必须事先存在。

另外,MySQL Server必须具有在文件系统中创建目录所需的写权限
注意:本地克隆操作不支持克隆位于数据目录外部的用户创建的表或表空间。
尝试克隆此类表或表空间会导致报错:

ERROR 1086 (HY000): File '/path/to/tablespace_name.ibd' already exists.。
克隆操作时如果指定了一个与数据源表空间相同路径时会导致冲突,因此被禁止

重要提示:

当执行克隆操作时,所有用户创建的InnoDB表和表空间,InnoDB系统表空间,redo log和undo log表空间都将被克隆到指定目录下
注意:克隆操作只会克隆数据文件,除了系统变量datadir之外,
如果系统变量innodb_data_home_dir、innodb_data_file_path、innodb_log_group_home_dir、innodb_undo_directory单独指定了不同于datadir指定的路径,则也会被执行克隆,
系统变量socket、pid-file、tmpdir、log-error、slow_query_log_file、log-bin、relay-log指定路径下的文件不会被克隆

如果需要,可以在克隆操作完成后使用克隆的数据目录启动一个新的MySQL Server,例如:

#其中clone_dir是克隆操作完成之后的数据副本目录
shell> mysqld_safe --datadir=clone_dir

#示例
先将第二个MySQL Server的配置文件设置好,不能与同一个主机中其他MySQL Server的配置文件存在路径冲突,也不能存在端口冲突,然后,使用mysqld_safe启动第二MySQL Server,使用--datadir指定克隆的数据副本目录。
由于原先的实例开启了innodb_undo_directory 存放undolog的日志,然而指定目录/data/mysql/mydata_clone 克隆完成后,undolog日志存放了/data/mysql/mydata_clone 这个下面,所以clonemy8.cnf配置文件要重新指定innodb_undo_directory=/data/mysql/mydata_clone,才能基于clone副本数据正常启动新的实例

 mysqld_safe --defaults-file=/data/mysql/clonemy8.cnf --datadir=/data/mysql/mydata_clone &
 当然mysqld  --defaults-file=/data/mysql/clonemy8.cnf --datadir=/data/mysql/mydata_clone &  也可以启动的

本地指定目录克隆后,重启新实例的mysql的配置文件需要修改的路径如下:

 [root@localhost ~]# egrep '3307|mydata_clone' /data/mysql/clonemy8.cnf 
port    = 3307
socket  = /tmp/mysql3307.sock
port    = 3307
datadir = /data/mysql/mydata_clone
socket  = /tmp/mysql3307.sock
pid-file = mysqldb3307.pid
innodb_undo_directory = /data/mysql/mydata_clone

查看clone状态:显示的失败,然而本地指定目录clone,事实上是成功的
因为指定DATA DIRECTORY,本地磁盘空间需要更多的空间(克隆数据+本地历史数据),不会自动重启MySQL实例


mysql> select * from performance_schema.clone_status;
+------+------+--------+-------------------------+----------+----------------+----------------+----------+-------------------------------------------------------------------------------+-------------+-----------------+---------------+
| ID   | PID  | STATE  | BEGIN_TIME              | END_TIME | SOURCE         | DESTINATION    | ERROR_NO | ERROR_MESSAGE                                                                 | BINLOG_FILE | BINLOG_POSITION | GTID_EXECUTED |
+------+------+--------+-------------------------+----------+----------------+----------------+----------+-------------------------------------------------------------------------------+-------------+-----------------+---------------+
|    1 |    0 | Failed | 2020-05-08 12:01:44.674 | NULL     | LOCAL INSTANCE | LOCAL INSTANCE |     1815 | Recovery failed. Please Retry Clone. For details, look into server error log. |             |               0 |               |
+------+------+--------+-------------------------+----------+----------------+----------------+----------+-------------------------------------------------------------------------------+-------------+-----------------+---------------+
1 row in set (0.00 sec)

mysql> select * from performance_schema.clone_progress;
+------+-----------+-----------+----------------------------+----------------------------+---------+------------+------------+---------+------------+---------------+
| ID   | STAGE     | STATE     | BEGIN_TIME                 | END_TIME                   | THREADS | ESTIMATE   | DATA       | NETWORK | DATA_SPEED | NETWORK_SPEED |
+------+-----------+-----------+----------------------------+----------------------------+---------+------------+------------+---------+------------+---------------+
|    1 | DROP DATA | Completed | 2020-05-08 12:01:44.674154 | 2020-05-08 12:01:44.674758 |       1 |          0 |          0 |       0 |          0 |             0 |
|    1 | FILE COPY | Completed | 2020-05-08 12:01:44.674812 | 2020-05-08 12:01:57.679768 |       2 | 1119999520 | 1119999520 |       0 |          0 |             0 |
|    1 | PAGE COPY | Completed | 2020-05-08 12:01:57.679858 | 2020-05-08 12:01:57.882701 |       2 |          0 |          0 |       0 |          0 |             0 |
|    1 | REDO COPY | Completed | 2020-05-08 12:01:57.882761 | 2020-05-08 12:01:58.084247 |       2 |       8192 |       8192 |       0 |          0 |             0 |
|    1 | FILE SYNC | Completed | 2020-05-08 12:01:58.084367 | 2020-05-08 12:02:21.137360 |       2 |          0 |          0 |       0 |          0 |             0 |
|    1 | RESTART   | Completed | 2020-05-08 12:02:21.137360 | 2020-05-08 12:17:37.276226 |       0 |          0 |          0 |       0 |          0 |             0 |
|    1 | RECOVERY  | Failed    | 2020-05-08 12:17:37.276226 | NULL                       |       0 |          0 |          0 |       0 |          0 |             0 |
+------+-----------+-----------+----------------------------+----------------------------+---------+------------+------------+---------+------------+---------------+
7 rows in set (0.00 sec)

mysql> 

提示:
手动启动MySQL Server后,可以连接到接收方MySQL Server检查performance_schema下的clone_progress和clone_status表,以验证克隆操作是否成功完成。对于RESTART语句也会执行相同的监控

4.2 克隆远程数据

4.2.1克隆远程数据语法介绍:

克隆插件支持以下语法来克隆远程数据,即,从远程MySQL Server(数据捐赠者,或称为donor节点)克隆数据并将其传输到执行克隆操作的MySQL Server(数据接收者,或称为recipient节点)
CLONE INSTANCE FROM 'user'@'host':port IDENTIFIED BY 'password' [DATA DIRECTORY [=] 'clone_dir'] [REQUIRE [NO] SSL];

以上语法中的一些关键字解释:
"user"是donor MySQL Server上的用于执行克隆操作的用户,需要具有对所有库所有表的BACKUP_ADMIN权限
"host"是donor MySQL Server的主机名或IP地址。不支持IPV6地址,但支持IPV6地址别名与IPV4地址
"port"是donor MySQL Server的端口号。(不支持mysqlx_port指定的X协议端口。也不支持通过MySQL Router连接到donor MySQL Server)
"password"是"user"的用户密码
"DATA DIRECTORY [=] 'clone_dir'" 是一个可选子句,用于在recipient节点上为要克隆的数据副本指定一个本地存放目录。
如果不希望删除recipient节点上数据目录中的现有数据,请使用此选项指定一个其他路径。
但需要指定一个绝对路径,并且该目录不能事先存在、MySQL Server必须具有创建目录所需的写访问权限。
如果在执行克隆操作时未使用可选的"DATA DIRECTORY [=] 'clone_dir'" 子句,则克隆操作将删除recipient节点数据目录中的现有数据,并用克隆数据副本来替换它,然后自动重新启动MySQL Server
"[REQUIRE [NO] SSL]" 用于显式指定在通过网络传输克隆数据时是否使用加密连接。
如果使用了该子句但不能满足SSL使用条件,则返回一个错误。
如果没有指定SSL子句,则克隆数据时默认会先尝试建立加密连接,但如果SSL连接尝试失败,则退回使用不安全连接。
另外,无论是否指定此子句,如果要克隆加密数据,则必须使用安全连接。
有关更多信息,请参见下文中"为克隆配置加密连接"部分,原文链接:https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-remote.html#clone-plugin-remote-ssl

注意:
默认情况下,驻留在发送方(donor节点)MySQL Server的数据目录中用户创建的InnoDB表和表空间,会被克隆到接收方(recipient节点)MySQL Server的数据目录中(接收方中与数据文件存放相关的系统变量指定的路径下)。
如果指定了"DATA DIRECTORY [=] 'clone_dir'"子句,则在接收方中会将克隆数据存放到指定的目录下
如果用户创建的InnoDB表和表空间位于发送方MySQL Server的数据目录之外,它们会被克隆到接收方MySQL Server的相同路径上。

如果在接收方MySQL Server的相同路径上存在相同文件(表或表空间文件),则会报错.默认情况下,InnoDB的系统表空间、redo log和undo log表空间被克隆到与donor节点上的相关系统变量指定的相同位置
(分别由系统变量innodb_data_home_dir和innodb_data_file_path、innodb_log_group_home_dir和innodb_undo_directory指定)。
因此,如果未指定DATA DIRECTORY [=] 'clone_dir'子句,请确保donor节点和recipient节点中的相关系统变量设了为相同路径,如果指定了DATA DIRECTORY [=] 'clone_dir'子句,那么这些表空间和日志将被克隆到指定的目录下
(但如果指定了克隆数据的存放目录,则所有的数据文件都会被存放到该目录下,因此,在使用这些集中存放的克隆数据文件来启动新的MySQL Server之前,你可能需要手动做一些路径调整)

4.2.2远程克隆的前提条件:

要执行远程克隆操作,克隆插件必须在发送方和接收方的MySQL Server上都是安装且都处于激活状态。有关安装说明,请参见"安装克隆插件"

执行远程克隆操作需要在发送方和接收方上都创建好用于克隆操作的MySQL用户(对于发送方和接收方上各自用户克隆的用户,其用户名和密码可以不相同),且授予足够的权限

  • 对于发送方,克隆用户需要BACKUP_ADMIN权限来访问和传输发送方的数据,并在克隆操作期间阻塞DDL操作
  • 对于接收方,克隆用户需要CLONE_ADMIN权限来替换接收方的数据,并在克隆操作期间阻塞DDL操作,并自动重新启动MySQL Server。
    注意:CLONE_ADMIN权限隐式地包含了BACKUP_ADMIN和SHUTDOWN权限。当执行远程克隆操作时(执行CLONE INSTANCE语句)会执行一些前提条件检查:

    • 发送方和接收方必须拥有相同的MySQL Server版本。注意:MySQL 8.0.17及更高版本支持克隆插件,低于MySQL 8.0.17版本不支持,可以使用:SELECT VERSION()语句查看版本号
    • 发送方和接收方MySQL Server必须运行在相同的操作系统和平台上。
      例如,如果donor节点运行在一个Linux 64位平台上,那么recipient节点也必须运行在Linux 64位平台上。有关如何确定操作系统平台的信息,请参阅操作系统相关文档
    • 接收方必须有足够的磁盘空间来存放克隆数据。默认情况下,在接收方中接收发送方的克隆数据之前会先删除接收方的数据,因此只需要按照发送方的数据大小来提供足够的磁盘空间即可。
      但如果使用了DATA DIRECTORY [=] 'clone_dir'子句将克隆数据存放到指定的目录下,则必须考虑接收方和发送方的数据总大小,以便提供足够存放两者数据大小的磁盘空间。
      可以通过检查文件系统上的数据目录大小和位于数据目录之外的任何表空间的大小来估计数据的大小。在估计发送方的数据大小时,请记住只有InnoDB数据是克隆的。
      如果在其他存储引擎中存储了数据,在估算克隆所需的磁盘空间时请注意排除这些数据文件的大小
  • InnoDB允许在数据目录(datadir系统变量指定的目录)之外创建一些表空间类型。如果发送方MySQL Server有驻留在数据目录之外的表空间,则克隆操作必须能够访问这些表空间。
    可以通过查询INFORMATION_SCHEMA.FILES表来识别位于数据目录之外的数据表空间有哪些,驻留在数据目录之外的数据表空间文件是一个绝对路径。
    查询语句:SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES

    root@localhost [(none)]>SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES;
    +-----------------------------------+
    | FILE_NAME                         |
    +-----------------------------------+
    | ./ibdata1                         |
    | ./ibtmp1                          |
    | /data/mysql/3307/undolog/undo_001 |
    | /data/mysql/3307/undolog/undo_002 |
    | ./mysql.ibd                       |
    | ./sys/sys_config.ibd              |
    +-----------------------------------+
    6 rows in set (0.00 sec)
    • 在发送方上处于激活状态的任何插件,也必须在接收方上处于活动状态。可以通过执行SHOW plugins语句或查询INFORMATION_SCHEMA.PLUGINS表来识别活跃状态的插件
    • 发送方和接收方必须具有相同的MySQL Server字符集和排序规则。有关MySQL Server字符集和排序配置的信息,请参阅:https://dev.mysql.com/doc/refman/8.0/en/charset-configuration.html
    • 发送方和接收方需要具有相同的innodb_page_size和innodb_data_file_path系统变量设置。在发送方和接收方上的innodb_data_file_path系统变量设置必须指定相同数量、相同大小的数据文件。
      可以使用SHOW VARIABLES语句检查各自的变量设置值。例如:SHOW VARIABLES LIKE 'innodb_page_size';SHOW VARIABLES LIKE 'innodb_data_file_path';

    • 如果克隆加密数据或压缩页数据,则发送方和接收方必须具有相同的文件系统块大小。
      对于页压缩数据,接收方的文件系统必须支持稀疏文件和打孔(文件系统的概念,可参考链接:http://www.voidcn.com/article/p-cwkauntz-bpz.html),以便在接收方的文件系统上打孔
      有关这些特性以及如何识别使用它们的表和表空间的信息,请参见下文中的"4、克隆加密数据"和"5、克隆压缩数据"。要确定文件系统块大小,请参阅操作系统相关的文档。

    • 如果要克隆加密数据,则需要启用安全连接。请参见下文中"为克隆配置加密连接"部分

    • 接收方上的系统变量clone_valid_donor_list的设置必须包含donor MySQL Server的主机地址。因为只能从有效的接收方列表中的主机克隆数据。
      如果要设置该系统变量,则需要用户具有SYSTEM_VARIABLES_ADMIN权限。在本节后面的远程克隆示例中提供了设置clone_valid_donor_list系统变量的说明。
      可以使用SHOW VARIABLES语句检查clone_valid_donor_list系统变量的设置。例如:SHOW VARIABLES LIKE 'clone_valid_donor_list'

    • 克隆操作只能串行执行,不能多个克隆操作并行执行,要确定是否有克隆操作正在运行,可以通过查询performance_schema.clone_status表进行确认,详情可参考"9、监控克隆操作"
    • 克隆插件以1MB大小的数据包和1M大小的元数据的形式传输数据。因此,在发送方和接收方的MySQL Server上,max_allowed_packet变量的最小值要求为2MB。
      小于2MB的max_allowed_packet变量值会导致报错。可以使用查询语句来检查max_allowed_packet变量的设置:SHOW VARIABLES LIKE 'max_allowed_packet'

    以下前提条件也适用于远程克隆操作:

    • UNDO表空间文件名必须是唯一的。当数据被从发送方克隆到接收方时,无论UNDO表空间在发送方上的什么位置下存放着,都会被克隆到接收方上的innodb_undo_directory系统变量指定的位置,或者被克隆到DATA DIRECTORY [=] 'clone_dir'子句指定的目录下(如果使用该子句的话)。
      从MySQL 8.0.18开始,如果在克隆操作期间遇到重复的undo表空间文件名,就会报告错误。在MySQL 8.0.18之前,克隆具有相同文件名的undo表空间可能会导致接收方上的undo表空间文件被覆盖。

    • 要查看UNDO表空间文件名以确保它们的名称是唯一的,可以通过查询INFORMATION_SCHEMA.FILES表,例如:SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE LIKE 'UNDO LOG'

    • 有关删除和添加undo表空间文件的信息,请参阅:https://dev.mysql.com/doc/refman/8.0/en/innodb-undo-tablespaces.html

    • 默认情况下,在克隆数据完成之后,将自动重新启动(停止和启动)接收方MySQL Server。
      要实现自动重启,必须在接收方上有一个监控进程来检测Server关闭。
      否则,在数据被克隆后、克隆操作停止、并关闭了接收方MySQL Server之后会报错:ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process)。
      此错误不表示克隆操作失败。这意味着在克隆数据之后,必须手动启动接收方MySQL Server。
      手动启动MySQL Server后,可以连接到接收方MySQL Server检查performance_schema下的clone_progress和clone_status表,以验证克隆操作是否成功完成。
      对于RESTART语句也会执行相同的监控。有关更多信息,请参见:https://dev.mysql.com/doc/refman/8.0/en/restart.html
      如果使用DATA DIRECTORY [=] 'clone_dir'子句克隆到指定目录,则不适用此要求,因为在此情况下不会执行自动重新启动MySQL Server
      (指定克隆目录的情况下,所有数据文件都被拷贝到了该目录下,实际启动MySQL Server时,配置文件中可能将redo log、undo log和数据文件指向了不同的路径)

    • 克隆插件支持多个系统变量用于控制远程克隆操作。在执行远程克隆操作之前,请检查系统变量并根据需要进行调整以适应你的运行环境。
      克隆相关的系统变量是在执行克隆操作的MySQL Server上设置的(接收方)。参见"12、克隆插件系统变量"

    克隆远程数据操作示例:默认情况下,远程克隆操作会删除接收方数据目录中的数据,用克隆的数据替换,然后重新启动MySQL Server
    (但指定了DATA DIRECTORY [=] 'clone_dir'子句时不会执行自动重启),该示例假设已经满足了所有的前提条件呢,详情参见上文

4.2.4、远程克隆数据:
环境:
192.168.1.105 master实例
192.168.1.182 新的实例
安装过程可以参考“三、安装克隆插件”,此处不再赘述。

开始操作演示:
192.168.1.105 机器发送端操作:

 使用管理用户登录到发送方 donor MySQL Server中,创建一个克隆用户并赋予BACKUP_ADMIN权限:
 root@localhost [(none)]> create user donor_clone_user@'192.168.1.%' identified by 'clone_test66';
Query OK, 0 rows affected (0.02 sec)

root@localhost [(none)]>grant backup_admin on *.* to donor_clone_user@'192.168.1.%';
Query OK, 0 rows affected (0.02 sec)

在donor MySQL Server中安装克隆插件:
root@localhost [(none)]>INSTALL PLUGIN clone SONAME 'mysql_clone.so';
ERROR 1125 (HY000): Function 'clone' already exists

192.168.1.182接受方机器操作:

使用管理用户登录到接收方MySQL Server,创建一个克隆用户并赋予CLONE_ADMIN权限:

root@localhost [(none)]>create user recipient_clone_user@'192.168.1.%' identified by 'clone_test66';
root@localhost [(none)]>grant clone_admin on *.* to recipient_clone_user@'192.168.1.%';
在接收方MySQL Server中安装克隆插件:
root@localhost [(none)]>INSTALL PLUGIN clone SONAME 'mysql_clone.so';
ERROR 1125 (HY000): Function 'clone' already exists

将donor MySQL Server的主机地址添加到接收方MySQL Server的clone_valid_donor_list变量中:
root@localhost [(none)]> SET GLOBAL clone_valid_donor_list = '192.168.1.105:3306';
以在donor MySQL Server中创建的克隆用户,登录到接收方MySQL Server中,执行如下克隆语句:(指定克隆目录操作)
root@localhost [(none)]>CLONE INSTANCE FROM 'donor_clone_user'@'192.168.1.105':3306 IDENTIFIED BY 'clone_test66' DATA DIRECTORY = '/data/mysql/3307/clone_data';
Query OK, 0 rows affected (24.72 sec)

查看克隆状态:
root@localhost [performance_schema]>select * from clone_status\G
*************************** 1. row ***************************
             ID: 1
            PID: 9
          STATE: Completed
     BEGIN_TIME: 2020-05-08 16:34:20.646
       END_TIME: 2020-05-08 16:34:45.358
         SOURCE: 192.168.1.105:3306
    DESTINATION: /data/mysql/3307/clone_data/
       ERROR_NO: 0
  ERROR_MESSAGE: 
    BINLOG_FILE: 
BINLOG_POSITION: 0
  GTID_EXECUTED: 
1 row in set (0.00 sec)

root@localhost [performance_schema]>select * from clone_progress;
+------+-----------+-------------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
| ID   | STAGE     | STATE       | BEGIN_TIME                 | END_TIME                   | THREADS | ESTIMATE   | DATA       | NETWORK    | DATA_SPEED | NETWORK_SPEED |
+------+-----------+-------------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
|    1 | DROP DATA | Completed   | 2020-05-08 16:34:20.769263 | 2020-05-08 16:34:20.871097 |       1 |          0 |          0 |          0 |          0 |             0 |
|    1 | FILE COPY | Completed   | 2020-05-08 16:34:20.871379 | 2020-05-08 16:34:31.474627 |       4 | 1119999445 | 1119999445 | 1120067369 |          0 |             0 |
|    1 | PAGE COPY | Completed   | 2020-05-08 16:34:31.474938 | 2020-05-08 16:34:31.776621 |       4 |          0 |          0 |        393 |          0 |             0 |
|    1 | REDO COPY | Completed   | 2020-05-08 16:34:31.777004 | 2020-05-08 16:34:32.077628 |       4 |       2560 |       2560 |       3325 |          0 |             0 |
|    1 | FILE SYNC | Completed   | 2020-05-08 16:34:32.077900 | 2020-05-08 16:34:45.357769 |       4 |          0 |          0 |          0 |          0 |             0 |
|    1 | RESTART   | Not Started | NULL                       | NULL                       |       0 |          0 |          0 |          0 |          0 |             0 |
|    1 | RECOVERY  | Not Started | NULL                       | NULL                       |       0 |          0 |          0 |          0 |          0 |             0 |
+------+-----------+-------------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
7 rows in set (0.00 sec)

克隆到指定目录说明:
默认情况下,远程克隆操作会删除接收方数据目录中的数据,并用克隆的数据替换它。
通过克隆到指定目录,可以避免接收方数据目录中的现有数据被删除,也不会执行重启MySQL Server的操作。
将数据克隆到指定目录的过程与不指定目录的克隆远程数据过程相同,但有一点区别,前者的克隆语句必须包含DATA DIRECTORY [=] 'clone_dir'子句。
例如:CLONE INSTANCE FROM 'donor_clone_user'@'192.168.1.105':3306 IDENTIFIED BY 'clone_test66' DATA DIRECTORY = '/data/mysql/3307/clone_data';
其中,DATA DIRECTORY子句需要指定一个绝对路径,且该目录不能事先存在,MySQL Server必须具有创建目录所需的写访问权限

克隆到指定目录时,在克隆数据完成之后,不会自动重新启动接收方MySQL Server。
如果你想使用指定目录启动MySQL Server,你必须手动修改一些文件的目录调整之后再执行启动,或者直接使用新的my.cnf配置文件,
在启动时将--datadir选项指定到克隆数据所在的目录,例如:mysqld_safe --datadir=/data/mysql/3307/clone_data
由于配置文件制定了undo文件存放目录,所以也要修改下:

[root@mysql-redis182 ~]# grep -w 'clone_data' /data/mysql/3307/my8.cnf 
datadir = /data/mysql/3307/clone_data
innodb_undo_directory = /data/mysql/3307/clone_data

然后启动mysql服务:


/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/3307/my8.cnf & 
登录192.168.1.182 发现主库192.168.1.105上创建的数据已经clone本地了
root@localhost [(none)]>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test001            |
| test002            |
+--------------------+
6 rows in set (0.01 sec)

root@localhost [(none)]>select user,host from mysql.user;
+------------------+-------------+
| user             | host        |
+------------------+-------------+
| donor_clone_user | 192.168.1.% |
| mysql.infoschema | localhost   |
| mysql.session    | localhost   |
| mysql.sys        | localhost   |
| root             | localhost   |
+------------------+-------------+
5 rows in set (0.00 sec)

启动克隆版的MySQL,查看接受放的二进制日志位置和gtid信息:

克隆操作结束之后,可在执行克隆操作的MySQL Server上执行如下查询语句,以检查发送给接收方的二进制日志位置:

root@localhost [(none)]>SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
+------------------+-----------------+
| BINLOG_FILE      | BINLOG_POSITION |
+------------------+-----------------+
| mysql-bin.000002 |            2463 |
+------------------+-----------------+
1 row in set (0.01 sec)

在克隆操作结束之后,可在执行克隆操作的MySQL Server上执行如下查询,以检查传输给接收方的GTID SET:

root@localhost [(none)]>SELECT @@GLOBAL.GTID_EXECUTED;
+------------------------------------------------------------------------------------+
| @@GLOBAL.GTID_EXECUTED                                                             |
+------------------------------------------------------------------------------------+
| e03f6a3a-90f8-11ea-9e29-842b2b72175e:1-9,
fb9ad95e-9104-11ea-ab74-b82a72cec95c:1-3 |
+------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

提示:当在192.168.1.182机器接受端未指定克隆目录操作,会清空当前192.168.1.182mysql实例数据目录下的数据,然后把克隆的数据复制过来,并且会自动重启mysql服务,由于undolog日志路径变化导致重启失败
登录到接收方192.168.1.182MySQL Server中,执行如下克隆语句:(未指定克隆目录操作)
root@localhost [(none)]> CLONE INSTANCE FROM 'donor_clone_user'@'192.168.1.105':3306 IDENTIFIED BY 'clone_test66' ;
ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process).

五、利用远程克隆的数据进行复制拓扑扩展应用介绍:

当在发送方上设置master_info_repository=TABLE和relay_log_info_repository=TABLE时(这是MySQL 8.0的默认设置),如果发送方是一个从库角色,那么从库的状态日志会被保存在表中,这些表在克隆操作期间会从发送方当做数据复制到接收方。
从库的状态日志中保存了与复制相关的配置设置,这些设置可用于在克隆操作成功之后正确地自动恢复复制
(如果配置文件中没有设置skip_slave_start参数,则在克隆操作完成之后会自动启动复制线程,另外,如果发送方不是从库而是主库,那么从库的状态日志表中并不存在复制配置信息,因此不适用,恢复复制过程中需要手动执行CHANGE MASTER语句进行配置)。

在MySQL 8.0.17和8.0.18中,只有mysql.slave_master_info表才会被复制到接收方(主库信息日志)
从MySQL 8.0.19开始,mysql.slave_relay_log_info(中继日志信息日志)和mysql.slave_worker_info(从库worker线程日志)也会被复制到接收方
PS:有关上述三张表中每个表包含的内容列表及其含义,请参阅:https://dev.mysql.com/doc/refman/8.0/en/slave-logs-status.html
注意,如果在发送方上设置了master_info_repository=FILE和relay_log_info_repository=FILE(这不是MySQL 8.0的默认设置,并且是不推荐的),则不会克隆从库的状态日志,只有在发送方设置master_info_repository=TABLE和relay_log_info_repository=TABLE时才会克隆从库的状态日志信息。

要在复制拓扑中使用克隆,请按照以下步骤执行:
对于用于组复制的新组成员,请先按照链接:https://dev.mysql.com/doc/refman/8.0/en/group-replication-adding-instances.html 中的说明为组复制配置好MySQL Server环境,且按照链接:https://dev.mysql.com/doc/refman/8.0/en/group-replication-cloning.html的说明设置好克隆功能所需的前提条件
然后,在joiner成员上执行START GROUP_REPLICATION语句时,克隆操作由组复制自动管理,因此不需要手动执行joiner成员加入组的操作,也不需要在joiner成员上执行任何进一步的设置步骤。

对于主从复制拓扑中的从库,首先在从库(接收方)中手动执行远程克隆操作语句,将数据从donor MySQL Server克隆到接收方。
在复制拓扑中,发送方必须是主库或从库。如果发送方是主库的,则后续需要手动执行CHANGE MASTER语句来配置复制,如果发送方是从库的,则不需要手动执行复制配置操作,复制能够通过克隆数据进行自动恢复复制
(配置文件中指定了skip_slave_start参数的情况除外)。有关克隆语句的详细信息,请参见"3、克隆远程数据"

克隆操作成功完成后,如果要在接收方MySQL Server上使用与发送方相同的复制通道,请验证其中哪些设置或配置可以在主从复制拓扑中自动恢复,哪些需要手动设置才能恢复。

  • 对于基于GTID的复制,如果在接收方配置了gtid_mode=ON,并且在发送方设置了gtid_mode=ON、ON_PERMISSIVE或 OFF_PERMISSIVE值,则接收方的gtid_executed系统变量中的GTID SET会作为接收方的GTID SET。
    如果接收方的数据是从拓扑中已经存在的一个从库中克隆出来的,则在启用了GTID自动定位(由CHANGE MASTER TO语句上的MASTER_AUTO_POSITION选项指定)的接收方上的复制通道可以在自动重启MySQL Server之后自动恢复,不需要执行任何手动设置(如果需要修改复制通道,则自行调整,这里不做赘述)

  • 对于基于二进制日志文件位置的复制,如果接收方使用的是MySQL 8.0.17或8.0.18,则来自发送方的二进制日志位置不应用于接收方,仅记录在performance_schema.clone_status表中。
    因此,在自动重启实例之后,必须在接收方中手动为复制通道设置使用基于二进制日志文件位置的复制,以便恢复复制。
    在这种情况下,需要确保在重启实例时启用skip_slave_start来避免复制自动启动,因为此时并未设置二进制日志位置,自动启动复制将尝试从头开始复制。

  • 对于基于二进制日志文件位置的复制,如果接收方使用的是MySQL 8.0.19或以上版本,则来自发送方的二进制日志位置将应用于接收方。
    接收方上使用基于二进制日志文件位置的复制,将会在自动重启复制通道之前,使用中继日志信息自动尝试执行中继日志的恢复过程。
    注意:对於单线程的从库(slave_parallel_workers设置为0),在没有任何其他意外发生的情况下,复制通道无需进一步设置即可成功恢复复制。
    对于多线程的从库(slave_parallel_workers大于0),中继日志恢复可能会失败,因为它通常不能自动完成。在这种情况下,会发出一条错误消息,您必须手动设置通道

5.1利用远程克隆数据,部署基于gtid主从复制搭建

在mysql8.0上是不支持如下的授权方式:

192.168.1.105 master库操作:
错误的授权姿势

root@localhost [test001]>grant replication slave on *.* to novelrep@'192.168.1.182' identified by 'JuwoSdk21TbUser'; flush privileges;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by 'JuwoSdk21TbUser'' at line 1
Query OK, 0 rows affected (0.02 sec)

正确的授权姿势

root@localhost [test001]>create user novelrep@'192.168.1.182' identified by 'JuwoSdk21TbUser'; grant replication slave on *.* to novelrep@'192.168.1.182';
Query OK, 0 rows affected (0.03 sec)

Query OK, 0 rows affected (0.00 sec)
CHANGE MASTER TO MASTER_HOST='192.168.1.105',MASTER_PORT=3306,MASTER_USER='novelrep',MASTER_PASSWORD='JuwoSdk21TbUser',MASTER_AUTO_POSITION = 1;start slave;
报错:
Last_IO_Errno: 2061
            Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 60 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.

解决办法:

    root@localhost [(none)]>create user novelrep@'192.168.1.182' identified WITH 'mysql_native_password' by 'JuwoSdk21TbUser'; grant replication slave on *.* to novelrep@'192.168.1.182';
Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.00 sec)

192.168.1.182库操作:

    CHANGE MASTER TO MASTER_HOST='192.168.1.105',MASTER_PORT=3306,MASTER_USER='novelrep',MASTER_PASSWORD='JuwoSdk21TbUser',MASTER_AUTO_POSITION = 1;start slave;        
  Last_IO_Errno: 13117
                Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

原因是server_id冲突了

解决办法:修改192.168.1.182上的server-id
show slave status\G 自动恢复复制,复制正常

六、克隆插件回顾总结

6.1本地clone+还原注意事项:

5.1只克隆innodb存储引擎的数据。非INNODB引擎的表只会生成空表。
5.2 不会克隆原实例的全部目录结构,只克隆了data目录下的相关数据。
5.3 克隆的目标目录必须不存在,克隆过程会生成该目录,所以原实例的启动账户要有创建目录的权限。
5.4 克隆后的目录会自动设置:mysql:mysql
5.5 克隆目标目录不会生成原实例自定义的innodb_undo_directory
5.6 克隆不会拷贝原实例的binlog文件

6.2远程克隆数据注意事项:

执行CLONE INSTANCE在非donor实例上执行。
不指定DATA DIRECTORY,将先清空本地数据,再做克隆拷贝,并自动重启MySQL实例(建议mysqld_safe启动)。
若指定DATA DIRECTORY,本地磁盘空间需要更多的空间(克隆数据+本地历史数据),不会自动重启MySQL实例
donor 和 recipient的MySQL版本要一致,并且至少8.0.17或者更高的版本。
donor 和 recipient的操作系统不能跨平台。
donor 和 recipient需要具有相同的字符集和排序规则。
donor和 recipient需要设置相同的 innodb_page_size and innodb_data_file_path
如果克隆了加密或者页压缩的数据,donor 和 recipient需要保持一样的文件系统块大小。
克隆命令将以1MB的包大小传输,所以donor 和 recipient的 max_allowed_packet至少要设置2MB。

6.3.其他注意事项

克隆操作期间不允许DDL(包括TRUNCATE TABLE)。
一次只能克隆一个MySQL实例。不支持在单个克隆操作中克隆多个MySQL实例。
远程克隆操作(在CLONE INSTANCE语句中指定Donor的MySQL服务器实例的端口号时)不支持mysqlx_port指定的X协议端口。
clone插件不支持MySQL配置参数的克隆。
clone插件不支持二进制日志的克隆。
克隆插件仅克隆存储在InnoDB中的数据。其他存储引擎数据未克隆。存储在任何数据库(包括sys模式)中的MyISAM和CSV表都被克隆为空表

鸣谢:本博文是在学些了马蜂窝高级DBA张充和爱可生高级DBA罗小波分享在知书堂微信公众号的关于MySQL8.0的clone plugin插件的文章。结合自己的理解总结于此。特别感谢二位的分享。同时我也分享出来,希望能帮助到更多的爱好MySQL伙伴,一起交流,一起成长。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章