这个是一年前(2019-07-22)出的一个新功能(什么?已经一年多了?)。
以插件的形式提供,用于将一个新实例从本地或者远程中克隆(实例级别)。
角色定义
Donor
:理解为源就好Recipient
:目标实例,新的实例(执行clone sql捞数据的)
(图源底下的文档)
安装
8.0.17+
的@@plugin_dir
有一个mysql_clone.so
的插件,自带的,一把梭就可:
mysql> SELECT @@version;
+-----------+
| @@version |
+-----------+
| 8.0.21 |
+-----------+
1 row in set (0.00 sec)
mysql> SELECT @@plugin_dir;
+--------------------------------+
| @@plugin_dir |
+--------------------------------+
| /data/mysql80-base/lib/plugin/ |
+--------------------------------+
1 row in set (0.00 sec)
mysql> \! ls /data/mysql80-base/lib/plugin/ | grep clone
mysql_clone.so
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
Query OK, 0 rows affected (0.01 sec)复制
权限需求
BACKUP_ADMIN
:【donor】为了阻塞DDL,需要持有backup lockCLONE_ADMIN
:【recipient】,这个权限其实包含BACKUP_ADMIN和SHUTDOWN(8.0权限文档看一下就知道了)SYSTEM_VARIABLES_ADMIN
或SUPER
:【recipient】,因为需要做SET GLOBALSELECT ON performance_schema.*
:【recipient】多一个SELECT权限给recipient也可,方便查询P_S中的视图以检查clone进度
开始搞事(测试clone remote data)
donor
上创建数据:
mysql> \R donor >
PROMPT set to 'donor > '
donor > CREATE DATABASE test;
Query OK, 1 row affected (0.00 sec)
donor > CREATE TABLE test.oct
> (id int key auto_increment, t varchar(64));
Query OK, 0 rows affected (0.01 sec)
donor > INSERT INTO test.oct SELECT null, '国泰民安,阖家团圆';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0复制
recipient
上设置@@global.clone_valid_donor_list
该值附录: This setting is applied on the recipient MySQL server instance. A comma-separated list of values is permitted in the following format: “HOST1:PORT1,HOST2:PORT2,HOST3:PORT3”. Spaces are not permitted.
mysql> \R recipient >
PROMPT set to 'recipient > '
recipient > SET @@global.clone_valid_donor_list = '10.9.87.173:3306';
Query OK, 0 rows affected (0.00 sec)复制
recipient
开始克隆
recipient > CLONE INSTANCE FROM clone_user@10.9.87.173:3306 IDENTIFIED BY 'clone_user';
Query OK, 0 rows affected (1.24 sec)
-- 卡了一下,返回OK没报错的感觉真好
recipient > Restarting mysqld...
2020-10-01T05:48:15.962868Z mysqld_safe Number of processes running now: 0
2020-10-01T05:48:15.966013Z mysqld_safe mysqld restarted
-- 上面的输出不一定有,因为我是用同一个终端会话启动的mysqld_safe,
所以此处打印出来了。复制
完事。
检查下在donor
上新增的数据有没有过来:
recipient > SELECT * FROM test.oct;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 8
Current database: *** NONE ***
+----+-----------------------------+
| id | t |
+----+-----------------------------+
| 1 | 国泰民安,阖家团圆 |
+----+-----------------------------+
1 row in set (0.01 sec)复制
复制相关
可以看一下recipient
上的gtid
信息,方便建立复制:
recipient > SELECT @@GLOBAL.GTID_EXECUTED;
+------------------------------------------+
| @@GLOBAL.GTID_EXECUTED |
+------------------------------------------+
| 66ce6625-03a6-11eb-81ef-5254005ab547:1-9 |
+------------------------------------------+
1 row in set (0.00 sec)
recipient > SELECT @@server_uuid;
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| 68a8cdff-03a6-11eb-bc34-5254000d61a2 |
+--------------------------------------+
1 row in set (0.00 sec)
-- 可见,gtid来源于donor。
mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
+------------------------+-----------------+
| BINLOG_FILE | BINLOG_POSITION |
+------------------------+-----------------+
| 10-9-87-173-bin.000003 | 418 |
+------------------------+-----------------+
1 row in set (0.00 sec)
-- 当然看file和pos也是可以的啦。复制
还有一些细节也可以看手册了解。
比如想一下上述信息来源于哪里,mysql schema下的哪些信息被clone了过来等。
检查进度 & 执行过程
整个过程执行步骤如下:
recipient > SELECT stage, state FROM performance_schema.clone_progress;
+-----------+-----------+
| stage | state |
+-----------+-----------+
| DROP DATA | Completed |
| FILE COPY | Completed |
| PAGE COPY | Completed |
| REDO COPY | Completed |
| FILE SYNC | Completed |
| RESTART | Completed |
| RECOVERY | Completed |
+-----------+-----------+
7 rows in set (0.00 sec)复制
三个核心步骤:
FILE COPY
:先开启page tracking
,用于盯着在克隆过程中的新增的DML操作对page的修改。然后按文件进行拷贝,类似于xtrabackup的ibd copy。PAGE COPY
:开启redo archiving
,细节下次写或者google就可知。REDO COPY
:类似于xtrabackup的redo copy,完了之后加一个短暂的锁,记录binlog file和pos,也记录gtid信息。
或者简单看这个worklog
如下
Take backup lock to prevent any more DDL in recipient.
Drop all existing user tablespace/data :
reduces the DB size for re-provisioningClone from remote instance in place
for user tablespace files copy as it is
for all system files keep it as .clone
e.g. for DD mysqld.ibd.cloneRestart server
Replace system files from .clone
usual server start up [initialize DD, built-in plugin etc.]
allow users to connect
更多的细节,如果像我一样比较憨看不懂几行源码,直接去翻官方的worklog
。
关于监控
每一步的步骤和监控可以直接SELECT *去查P_S的该视图,该视图提供了很详细的监控:
recipient > SHOW CREATE TABLE performance_schema.clone_progress\G
*************************** 1. row ***************************
Table: clone_progress
Create Table: CREATE TABLE `clone_progress` (
`ID` int DEFAULT NULL,
`STAGE` char(32) DEFAULT NULL,
`STATE` char(16) DEFAULT NULL,
`BEGIN_TIME` timestamp(6) NULL DEFAULT NULL,
`END_TIME` timestamp(6) NULL DEFAULT NULL,
`THREADS` int DEFAULT NULL,
`ESTIMATE` bigint DEFAULT NULL,
`DATA` bigint DEFAULT NULL,
`NETWORK` bigint DEFAULT NULL,
`DATA_SPEED` int DEFAULT NULL,
`NETWORK_SPEED` int DEFAULT NULL
) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)复制
更细的监控可以开启P_S底下的更多视图,也请翻阅文档了解。
限制
两个节点都需要安装
clone plugin
版本:
MySQL 8.0.17+
两个节点平台相同
两个节点
MySQL Server
需要相同的字符集和排序规则recipient
磁盘空间足够@@innodb_data_file_path
相同@@innodb_page_size
相同@@max_allowed_packet
至少大于等于2MB
(The clone plugin transfers data in 1MB packets plus metadata)仅支持
InnoDB
一次只能克隆一个实例
不支持克隆
binlog
…… (点点点的部分可看手册)
其他
简单看一下CLONE
语法:
可以指定目录。如果不指定目录,默认就按recipient
的datadir
了(When the optional DATA DIRECTORY [=] 'clone_dir' clause is not used, a cloning operation removes existing data in the recipient data directory, replaces it with the cloned data)。
同时,看起来也是支持SSL
的。
mysql> HELP CLONE;
Name: 'CLONE'
Description:
Syntax:
CLONE clone_action
clone_action: {
LOCAL DATA DIRECTORY [=] 'clone_dir';
| INSTANCE FROM 'user'@'host':port
IDENTIFIED BY 'password'
[DATA DIRECTORY [=] 'clone_dir']
[REQUIRE [NO] SSL]
}复制
执行的时候,recipient
实例不要弄错了,因为如果不指定data directory
,会将recipient
对应datadir
里的现有数据都删掉。(不要搞出大事)
适用场景
大致想了一下适用场景:
重建从库(替代
xtrabackup
)实例迁移(故障机迁移之类?)
MGR环境中新增节点or掉线恢复等
总之,可以通过clone plugin
快速获得一个逻辑时间一致的,静态的数据副本。
至于增量数据,因为这个玩意会输出gtid
与binlog position
信息,所以可以比较简单的将clone plugin包装成一个工具,做增量复制。
真香。
参考文档
Clone: Create MySQL instance replica:
https://mysqlserverteam.com/clone-create-mysql-instance-replica/5.6.7 The Clone Plugin:
https://dev.mysql.com/doc/refman/8.0/en/clone-plugin.html
相关阅读
并行逻辑备份恢复了解一下:
单表迁移/恢复了解一下:
Transportable TableSpace(TTS) 使用详解
-- the end --
戳阅读原文查看历史推送。