一 简介
最近几天看了 Clone Plugin 技术,克隆技术是MySQL 8.0.17 引入的一个重大特性,从产品的角度来看 该技术旨在解决 MRG 横向扩容的问题,除了快速恢复一个实例,其他的使用场景有限。
本文先通过动手实践来了解 clone plugin的基础使用方式。后面的文章再去深入了解 clone plugin的 工作原理和限制,注意事项等等。
二 实践
2.1 安装 clone 插件
MySQL clone plugin 有两种安装方式:
在my.cnf 中配置:
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT ## 非强制复制
clone 有四个值:
ON(开启插件)
OFF(禁用插件),
FORCE(强制开启。如果插件初始化失败,MySQL将不会启动)
FORCE_PLUS_PERMANENT(在FORCE的基础上,不允许通过UNINSTALL PLUGIN命令卸载插件)。复制
在 clone=FORCE_PLUS_PERMANENT
的情况下卸载会报错:
mysql {root} ((none)) > uninstall plugin clone;
ERROR 1702 (HY000): Plugin 'clone' is force_plus_permanent and can not be unloaded复制
动态加载
## 安装插件
mysql {root} ((none)) > INSTALL PLUGIN clone SONAME 'mysql_clone.so';
Query OK, 0 rows affected (0.01 sec)
## 然后查看安装是否成功:
mysql {root} ((none)) > SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone | ACTIVE |
+-------------+---------------+复制
PLUGIN_STATUS 状态显示为 ACTIVE 代表插件加载成功。
2.2 使用方式
克隆支持2种方式 本地克隆和远程克隆,
2.2.1 本地克隆
本地克隆就是将数据库复制到本机指定的位置,大家可以考虑该功能的实际使用场景,比如测试环境可以临时恢复实例 。
安装插件
mysql {root} ((none)) > INSTALL PLUGIN clone SONAME 'mysql_clone.so';
Query OK, 0 rows affected (0.01 sec)
mysql {root} ((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)
mysql {root} ((none)) > create user donor_clone_user@'%' identified by 'clone#123';
Query OK, 0 rows affected (0.01 sec)
mysql {root} ((none)) > grant backup_admin on *.* to donor_clone_user@'%';
Query OK, 0 rows affected (0.00 sec)复制
使用 donor_clone_user
用户登陆数据库并执行 clone 的命令 ,本地克隆的语法为
CLONE LOCAL DATA DIRECTORY [=] 'clone_dir';
复制
其中 clone_dir
上层目录一定要存在并且 mysql 用户对该目录有读写权限,否则会报权限不足。比如 clone_dir
=/data/mysql/clone_mysql_20230519/ 其中
clone_dir
目录必须是绝对路径, data/mysql/clone_mysql_20230519/ 。/data/mysql/ 一定要存在,并且 mysql 有读写权限。 clone_mysql_20230519
不能存在,clone 命令会创建绝对目录下的子目录clone_mysql_20230519
创建测试数据
mysql {root} ((none)) > create database test;
Query OK, 1 row affected (0.00 sec)
mysql {root} ((none)) > use test;
mysql {root} (test) > create table t1(id int);
Query OK, 0 rows affected (0.01 sec)
mysql {root} (test) > insert into t1 values(1),(2),(3),(4),(5);
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql {root} (test) > select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+------+
5 rows in set (0.00 sec)复制
可以使用 root 或者用户 donor_clone_user
执行clone命令,用户必须有 backup_admin
权限。
mysql {root} (test) > CLONE LOCAL DATA DIRECTORY = '/data/mysql/clone_data_20230518';
Query OK, 0 rows affected (0.19 sec)复制
查看 clone_data_20230519
目录:
[root@adbpg001 ~]# cd /data/mysql/clone_data_20230519/
[root@adbpg001 clone_data_20230519]# ll
总用量 69656
drwxr-x--- 2 mysql mysql 4096 5月 19 00:10 #clone
-rw-r----- 1 mysql mysql 3438 5月 19 00:10 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 5月 19 00:10 ibdata1
drwxr-x--- 2 mysql mysql 4096 5月 19 00:10 #innodb_redo
drwxr-x--- 2 mysql mysql 4096 5月 19 00:10 mysql
-rw-r----- 1 mysql mysql 25165824 5月 19 00:10 mysql.ibd
drwxr-x--- 2 mysql mysql 4096 5月 19 00:10 sys
drwxr-x--- 2 mysql mysql 4096 5月 19 00:10 test
-rw-r----- 1 mysql mysql 16777216 5月 19 00:10 undo_001
-rw-r----- 1 mysql mysql 16777216 5月 19 00:10 undo_002复制
这里我们看到 clone 命令拷贝的是 data_dir 目录下 数据库目录,undo,ibdata1 ,redolog 临时文件,ib_buffer_pool
,然后需要修改 my.cnf 基于此文件启动的数据库实例。感兴趣的朋友可以自己操作一下。
2.2.2 远程克隆
顾名思义,远程登陆是把源数据实例的数据克隆到目标机器,克隆的命令是从 目标段发起,将数据 克隆到本地。这里有两个角色概念:
基于远程克隆搭建主从
CLONE INSTANCE FROM 'user'@'host':port
IDENTIFIED BY 'password'
[DATA DIRECTORY [=] 'clone_dir']
[REQUIRE [NO] SSL];复制
参数说明:
user,password是 donor 上的克隆用户和密码。 host,port 是待克隆实例的(donor)的IP和端口,,需要 backup_admin
权限,如上面创建的donor_clone_user
。DATA DIRECTORY 指定备份目录,如果不指定的话,则默认克隆到 接收者(recipient) 的数据目录下。clone_dir 的要求和上面讲述的一致。 REQUIRE [NO] SSL,是否开启SSL通信。
准备工作
捐赠者 172.17.28.117 接收者 172.17.28.116
初始化测试环境
在源端和目标端 接收者上初始化实例,安装 插件,初始化用户
在172.17.28.117 上使用root 用户执行
create user clone_user@'%' identified by 'clone#123';
grant backup_admin on *.* to clone_user@'%';
## 安装 克隆插件
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
## 检查安装是否成功
SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';复制
在172.17.28.116 以 root 用户执行上执行
reate user clone_user@'%' identified by 'clone#123';
grant clone_admin, backup_admin on *.* to clone_user@'%';
## 安装 克隆插件
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
## 检查安装是否成功
SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
#### 设置 donor 名单
将捐赠者的实例 ip port 添加到接收方的 `clone_valid_donor_list` 变量中:
>SET GLOBAL clone_valid_donor_list = '172.17.28.117:3306';复制
注意
捐赠者和接收者上面的
clone_user
的权限不一样, clone操作的必须要backup_admin
权限,在接收者上的用户必须有clone_admin
,backup_admin
权限, 单独赋予clone_admin
,执行clone命令会报 权限不足的错误
mysql {clone_user} ((none)) > CLONE INSTANCE FROM 'clone_user'@'172.17.28.117':3306 IDENTIFIED BY 'clone#123' ;
ERROR 1227 (42000): Access denied; you need (at least one of) the BACKUP_ADMIN privilege(s) for this operation复制
执行 clone 命令
使用 clone_user
登陆数据库,执行如下命令
CLONE INSTANCE FROM 'clone_user'@'172.17.28.117':3306 IDENTIFIED BY 'clone#123';
这里分为两种场景吧 ,如果是以 mysqld 启动,clone命令执行完之后,需要重启,但是会启动失败
此时需要对数据库进行手工重启
复制
如果是以守护进程的方式启动mysql ,clone之后,重启是可以成功的。
关于 clone 之后重启失败的问题,可以参考 https://segmentfault.com/a/1190000040529340/en
三 小结
总体使用体验来说,如果要恢复一个实例,克隆的速度要比逻辑备份和xtrabackup 要快而且简单。可以作为日常运维的一个补充。
对于非 MGR的 生产环境,使用场景上还是有一定限制的,比如2T 实例,拷贝速度无法限速限流,会对 所在实例或者目标实例 的IO 有很大影响。
对于已经使用 MySQL 8.0 的朋友,大家可以 留言分享一些你们在运维过程中的使用clone 特性的实践。