1、MySQL 8.0 clone plugin简介
1) 克隆插件允许从本地或远程的MySQL Server中克隆数据。克隆的数据是存储在InnoDB中的schema(database)、table(表)、tablespaces(表空间)和data dictionary metadata(数据字典元数据)的物理快照。该物理快照实际上是一个功能完整的数据目录,MySQL克隆插件可以使用该数据目录来配置并恢复一个MySQL Server;
2) 本地克隆:指的是将数据从启动克隆操作的MySQL Server克隆到该MySQL Server的主机上的一个指定目录下。下图表示本地克隆操作的示意图:
3) 远程克隆:涉及到启动克隆操作的本地MySQL Server(称为"recipient",即,数据的接收者或接收方)和数据源所在的远程MySQL Server(称为"donor",即,数据的提供者或发送方),在接收方上启动远程克隆操作时,克隆的数据会通过网络从发送方传输到接收方。默认情况下,远程可能那个操作会删除接收方数据目录中的所有数据,并将其替换为克隆的新数据。如果不希望接收方中的现有数据被删除,你也可以在接收方中执行克隆操作时将克隆数据指定存放在其他目录中。下图表示远程克隆操作的示意图:
4)对于克隆的数据本身来说,本地克隆操作与远程克隆操作没有太大区别;
5)克隆插件支持在复制拓扑中使用。除了克隆数据外,克隆操作还能够从发送方中提取和传输复制坐标(二进制日志的位置),并将其应用于接收方,也就是说,我们可以使用克隆插件来在组复制中添加新的组成员,也可以在主从复制拓扑中添加新的从库。与通过二进制日志来复制大量事务相比,通过克隆插件要快得多,效率也更高;
2、安装克隆插件
1)在配置文件中添加,需要重启服务
[mysqld]
#插件
plugin-load-add=mysql_clone.so
2) 动态加载插件
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
#要验证插件是否安装成功,可以查看INFORMATION_SCHEMA.plugins表或者使用SHOW PLUGINS语句查看,例如:
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone | ACTIVE |
+-------------+---------------+
3、克隆本地数据
克隆插件支持用于在本地克隆数据的语法,即将数据从本地(相同主机)的一个MySQL Server的数据目录克隆到本地MySQL Server所在主机的一个指定目录下,使用克隆插件执行克隆本地数据的操作语法如下:
mysql> CLONE LOCAL DATA DIRECTORY [=] 'clone_dir';
# 前提需要一个用于执行克隆操作的MySQL用户。该用户可以是在"*.*"上(全局权限)具有BACKUP_ADMIN权限的任何MySQL用户
mysql> create user 'clone_user'@'%' identified by "clone_user";
mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user';
示例:
mysql> CLONE LOCAL DATA DIRECTORY = '/iddbs/data3308/data';
ERROR 1007 (HY000): Can't create database '/iddbs/data3308/data'; database exists
#在上述操作语句中,"/iddbs/data3308/data"是将数据克隆到本地目录的绝对路径。该路径中,"data"目录不能事先存在(事先存在会报错),但路径前缀"/iddbs/data3308/"必须事先存在。另外,MySQL Server必须具有在文件系统中创建目录所需的写权限。
mysql> CLONE LOCAL DATA DIRECTORY = '/iddbs/data3308/data';
Query OK, 0 rows affected (0.45 sec)
mysql>
mysql>
mysql> system ls -lh /iddbs/data3308/data
total 1.1G
drwxr-x---. 2 iddbs iddbs 89 May 8 02:21 #clone
-rw-r-----. 1 iddbs iddbs 3.6K May 8 02:21 ib_buffer_pool
-rw-r-----. 1 iddbs iddbs 1.0G May 8 02:21 ibdata1
-rw-r-----. 1 iddbs iddbs 8.0M May 8 02:21 ib_logfile0
-rw-r-----. 1 iddbs iddbs 8.0M May 8 02:21 ib_logfile1
drwxr-x---. 2 iddbs iddbs 6 May 8 02:21 mysql
-rw-r-----. 1 iddbs iddbs 24M May 8 02:21 mysql.ibd
drwxr-x---. 2 iddbs iddbs 28 May 8 02:21 sys
drwxr-x---. 2 iddbs iddbs 34 May 8 02:21 test01
-rw-r-----. 1 iddbs iddbs 16M May 8 02:21 undo_001
-rw-r-----. 1 iddbs iddbs 16M May 8 02:21 undo_002
mysql> system ls -lh /iddbs/data3307/data #原始目录
total 1.1G
-rw-r-----. 1 iddbs iddbs 56 Apr 21 02:58 auto.cnf
-rw-------. 1 iddbs iddbs 1.7K Apr 21 02:58 ca-key.pem
-rw-r--r--. 1 iddbs iddbs 1.1K Apr 21 02:58 ca.pem
-rw-r--r--. 1 iddbs iddbs 1.1K Apr 21 02:58 client-cert.pem
-rw-------. 1 iddbs iddbs 1.7K Apr 21 02:58 client-key.pem
-rw-r-----. 1 iddbs iddbs 768K May 8 01:59 #ib_16384_0.dblwr
-rw-r-----. 1 iddbs iddbs 8.8M Apr 21 02:58 #ib_16384_1.dblwr
drwxr-x---. 3 iddbs iddbs 22 May 8 01:57 #ib_archive
-rw-r-----. 1 iddbs iddbs 3.6K May 6 05:55 ib_buffer_pool
-rw-r-----. 1 iddbs iddbs 1.0G May 8 01:57 ibdata1
-rw-r-----. 1 iddbs iddbs 8.0M May 8 01:59 ib_logfile0
-rw-r-----. 1 iddbs iddbs 8.0M Apr 21 02:58 ib_logfile1
-rw-r-----. 1 iddbs iddbs 8.0M May 8 01:59 ib_logfile2
-rw-r-----. 1 iddbs iddbs 12M May 8 01:43 ibtmp1
drwxr-x---. 2 iddbs iddbs 187 May 8 01:42 #innodb_temp
drwxr-x---. 2 iddbs iddbs 143 Apr 21 02:58 mysql
-rw-r-----. 1 iddbs iddbs 24M May 8 01:57 mysql.ibd
drwxr-x---. 2 iddbs iddbs 8.0K May 8 01:46 performance_schema
-rw-------. 1 iddbs iddbs 1.7K Apr 21 02:58 private_key.pem
-rw-r--r--. 1 iddbs iddbs 452 Apr 21 02:58 public_key.pem
-rw-r--r--. 1 iddbs iddbs 1.1K Apr 21 02:58 server-cert.pem
-rw-------. 1 iddbs iddbs 1.7K Apr 21 02:58 server-key.pem
drwxr-x---. 2 iddbs iddbs 28 Apr 21 02:58 sys
drwxr-x---. 2 iddbs iddbs 34 Apr 21 04:08 test01
-rw-r-----. 1 iddbs iddbs 16M May 8 01:59 undo_001
-rw-r-----. 1 iddbs iddbs 16M May 8 01:59 undo_002
注意:当执行克隆操作时,所有用户创建的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,例如:
mysql8024/bin/mysqld_safe --defaults-file=/iddbs/data3308/my3308.cnf &
[1] 2702
[iddbs@host140 ~]# mysql8024/bin/mysql -uiddbs -piddbs -S data3308/my3308.sock
mysql> select @@datadir;
+----------------------+
| @@datadir |
+----------------------+
| /iddbs/data3308/data/ |
+----------------------+
PS:在克隆数据副本目录下,有一个“#clone”目录,如下:
[iddbs@host140 ~]# ll data3308/data/#clone/
total 12
-rw-r-----. 1 iddbs iddbs 119 May 8 02:24 #status_recovery
-rw-r-----. 1 iddbs iddbs 334 May 8 02:24 #view_progress
-rw-r-----. 1 iddbs iddbs 60 May 8 02:21 #view_status
其中#status_recovery记录了日志以及事务的事务号
cat \#status_recovery
1620455062554475
1620455064675491
/iddbs/data3307/binlog/mysql_bin.000008
748
f9e37b40-a26e-11eb-9b22-000c293bb7d1:1-28
4、克隆远程数据
克隆插件支持以下语法来克隆远程数据,即,从远程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
远程克隆的前提:
1、要执行远程克隆操作,克隆插件必须在发送方和接收方的MySQL Server上都是安装且都处于激活状态;
2、执行远程克隆操作需要在发送方和接收方上创建好用于克隆操作的MySQL用户(对于发送方和接收方上各自用户克隆的用户,其用户名和密码可以不相同),且授予足够的权限
* 对于发送方,克隆用户需要BACKUP_ADMIN权限来访问和传输发送方的数据,并在克隆操作期间阻塞DDL操作;
* 对于接收方,克隆用户需要CLONE_ADMIN权限来替换接收方的数据,并在克隆操作期间阻塞DDL操作,并自动重新启动MySQL Server。注意:CLONE_ADMIN权限隐式地包含了BACKUP_ADMIN和SHUTDOWN权限;
3、当执行远程克隆操作时(执行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'子句将克隆数据存放到指定的目录下,则必须考虑接收方和发送方的数据总大小,以便提供足够存放两者数据大小的磁盘空间;
* 在发送方上处于激活状态的任何插件,接收方上也须有且是活动状态。可以通过执行SHOW plugins语句或查询INFORMATION_SCHEMA.PLUGINS表来识别活跃状态的插件;
* 发送方和接收方必须具有相同的MySQL Server字符集和排序规则。有关MySQL Server字符集和排序配置的信息;
* 发送方和接收方需要具有相同的innodb_page_size和innodb_data_file_path系统变量设置。在发送方和接收方上的innodb_data_file_path系统变量设置必须指定相同数量、相同大小的数据文件。可以使用SHOW VARIABLES语句检查各自的变量设置值;
* 接收方上的系统变量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表进行确认;
* 克隆插件以1MB大小的数据包和1M大小的元数据的形式传输数据。因此,在发送方和接收方的MySQL Server上,max_allowed_packet变量的最小值要求为2MB。小于2MB的max_allowed_packet变量值会导致报错。可以使用查询语句来检查max_allowed_packet变量的设置:SHOW VARIABLES LIKE 'max_allowed_packet'
远程克隆的示例:
克隆远程数据操作示例:默认情况下,远程克隆操作会删除接收方数据目录中的数据,用克隆的数据替换,然后重新启动MySQL Server(但指定了DATA DIRECTORY [=] 'clone_dir'子句时不会执行自动重启)
# 使用管理用户登录到donor MySQL Server中,创建一个克隆用户并赋予BACKUP_ADMIN权限
mysql> create user donor_clone_user@'%' identified by 'letsg0';
Query OK, 0 rows affected (0.05 sec)
mysql> grant backup_admin on *.* to donor_clone_user@'%';
Query OK, 0 rows affected (0.00 sec)
使用管理用户登录到接收方MySQL Server,创建一个克隆用户并赋予
mysql> create user recipient_clone_user@'%' identified by 'letsg0';
Query OK, 0 rows affected (0.01 sec)
mysql> grant clone_admin on *.* to recipient_clone_user@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
Query OK, 0 rows affected (0.02 sec)
将donor MySQL Server的主机地址添加到接收方MySQL Server的clone_valid_donor_list变量中
mysql> show variables like '%clone_valid_donor_list%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| clone_valid_donor_list | |
+------------------------+-------+
1 row in set (0.01 sec)
mysql> SET GLOBAL clone_valid_donor_list = '192.168.221.140:3307';
Query OK, 0 rows affected (0.00 sec)
以在donor MySQL Server中创建的克隆用户,登录到接收方MySQL Server中,执行如下克隆语句:
mysql> CLONE INSTANCE FROM 'donor_clone_user'@'192.168.221.140':3307 IDENTIFIED BY 'letsg0' ;
ERROR 3862 (HY000): Clone Donor Error: Connect failed: 2003 : Can't connect to MySQL server on '192.168.221.140:3307' (113).
#注意防火墙,需要把主机的防火前关闭;
mysql> CLONE INSTANCE FROM 'donor_clone_user'@'192.168.221.140':3307 IDENTIFIED BY 'letsg0' ;
mysql> Restarting mysqld...
2021-05-08T08:49:57.136664Z mysqld_safe Number of processes running now: 0
2021-05-08T08:49:57.140654Z mysqld_safe mysqld restarted
克隆数据完成后,将自动重新启动接收方的MySQL Server。重启之后可以登录到接收方的MySQL Server中查看performance_schema下的克隆状态信息表,可以查看到克隆操作的状态和进度的信息:
mysql> use performance_schema;
mysql>
mysql>
mysql> select * from clone_status\G; #查看克隆进度和状态信息
*************************** 1. row ***************************
ID: 1
PID: 0
STATE: Completed
BEGIN_TIME: 2021-05-08 03:56:22.484
END_TIME: 2021-05-08 03:56:33.147
SOURCE: 192.168.221.140:3307
DESTINATION: LOCAL INSTANCE
ERROR_NO: 0
ERROR_MESSAGE:
BINLOG_FILE: mysql_bin.000008
BINLOG_POSITION: 1312
GTID_EXECUTED: f9e37b40-a26e-11eb-9b22-000c293bb7d1:1-30
1 row in set (0.01 sec)
ERROR:
No query specified
mysql> select * from clone_progress;
+------+-----------+-----------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
| ID | STAGE | STATE | BEGIN_TIME | END_TIME | THREADS | ESTIMATE | DATA | NETWORK | DATA_SPEED | NETWORK_SPEED |
+------+-----------+-----------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
| 1 | DROP DATA | Completed | 2021-05-08 03:56:22.647843 | 2021-05-08 03:56:22.894339 | 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | FILE COPY | Completed | 2021-05-08 03:56:22.895179 | 2021-05-08 03:56:27.554507 | 1 | 1132809826 | 1132809826 | 1132878607 | 0 | 0 |
| 1 | PAGE COPY | Completed | 2021-05-08 03:56:27.554744 | 2021-05-08 03:56:27.558627 | 1 | 0 | 0 | 99 | 0 | 0 |
| 1 | REDO COPY | Completed | 2021-05-08 03:56:27.558854 | 2021-05-08 03:56:27.564241 | 1 | 5632 | 5632 | 6029 | 0 | 0 |
| 1 | FILE SYNC | Completed | 2021-05-08 03:56:27.564527 | 2021-05-08 03:56:27.576689 | 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | RESTART | Completed | 2021-05-08 03:56:27.576689 | 2021-05-08 03:56:31.598073 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | RECOVERY | Completed | 2021-05-08 03:56:31.598073 | 2021-05-08 03:56:33.147005 | 0 | 0 | 0 | 0 | 0 | 0 |
+------+-----------+-----------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
7 rows in set (0.00 sec)
mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
+------------------+-----------------+
| BINLOG_FILE | BINLOG_POSITION |
+------------------+-----------------+
| mysql_bin.000008 | 1312 |
+------------------+-----------------+
1 row in set (0.00 sec)
mysql> SELECT @@GLOBAL.GTID_EXECUTED;
+-------------------------------------------+
| @@GLOBAL.GTID_EXECUTED |
+-------------------------------------------+
| f9e37b40-a26e-11eb-9b22-000c293bb7d1:1-30 |
+-------------------------------------------+
1 row in set (0.00 sec)
5、在复制拓扑中使用克隆
1) 对于主从复制拓扑中的从库,首先在从库(接收方)中手动执行远程克隆操作语句,将数据从donor MySQL Server克隆到接收方。在复制拓扑中,发送方必须是主库或从库。如果发送方是主库的,则后续需要手动执行CHANGE MASTER语句来配置复制,如下操作:
mysql> change master to master_user="rep",master_host="192.168.221.140",master_password="rep",master_port=3307,master_auto_position=1;
Query OK, 0 rows affected, 8 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql> show slave status\G;报如下错误
Last_IO_Error: Master command COM_REGISTER_SLAVE failed: Access denied for user 'rep'@'%' (using password: YES) (Errno: 1045)
原因是:rep账号没有replication slave权限,在主库添加复制账号的权限即可解决
如果发送方是从库的,则不需要手动执行复制配置操作,复制能够通过克隆数据进行自动恢复复制,在 skip_slave_start=1的情况下,只需要start slave即可
mysql> select * from performance_schema.clone_status\G;
*************************** 1. row ***************************
ID: 1
PID: 0
STATE: Completed
BEGIN_TIME: 2021-05-08 04:49:50.941
END_TIME: 2021-05-08 04:49:59.008
SOURCE: 192.168.221.200:3307
DESTINATION: LOCAL INSTANCE
ERROR_NO: 0
ERROR_MESSAGE:
BINLOG_FILE: mysql_bin.000002
BINLOG_POSITION: 1507
GTID_EXECUTED: f9e37b40-a26e-11eb-9b22-000c293bb7d1:1-35
1 row in set (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.221.140
Master_User: rep
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: mysql_bin.000008
Read_Master_Log_Pos: 2643
Relay_Log_File: relay_bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql_bin.000008
Slave_IO_Running: No
Slave_SQL_Running: No
mysql> start slave; #需要手动执行start slave
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.221.140
Master_User: rep
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: mysql_bin.000008
Read_Master_Log_Pos: 2643
Relay_Log_File: relay_bin.000002
Relay_Log_Pos: 418
Relay_Master_Log_File: mysql_bin.000008
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
2)组复制添加新成员(暂时未做)