暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL# 玩一玩8.0.17+ ClonePlugin

神谕的暗影长廊 2021-04-20
381

这个是一年前(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 lock

  • CLONE_ADMIN
    :【recipient】,这个权限其实包含BACKUP_ADMIN和SHUTDOWN(8.0权限文档看一下就知道了)

  • SYSTEM_VARIABLES_ADMIN
    SUPER
    :【recipient】,因为需要做SET GLOBAL

  • SELECT 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
如下

  1. Take backup lock to prevent any more DDL in recipient.

  2. Drop all existing user tablespace/data :
     reduces the DB size for re-provisioning

  3. Clone 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.clone

  4. Restart 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(32DEFAULT NULL,
  `STATE` char(16DEFAULT NULL,
  `BEGIN_TIME` timestamp(6NULL DEFAULT NULL,
  `END_TIME` timestamp(6NULL 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



相关阅读

并行逻辑备份恢复了解一下:

mydumper使用及原理浅析


单表迁移/恢复了解一下:

Transportable TableSpace(TTS) 使用详解






17真是个好数字啊,
想当年5.7.17出了MGR,
然后8.0.17出了Clone。




-- the end --






阅读原文查看历史推送。


文章转载自神谕的暗影长廊,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论