Skip to content

基于clone 插件复制MySQL数据

Clone Plugin是MySQL 8.0.17引入的一个重大特性 在8.0.17+ 在备份过程中会阻塞DDL操作,甚至影响后续的SELECT查询操作 在8.0.27+ 已经可以在备份过程中进行并发的DDL操作【不确定】

clone大致流程

数据库版本

sql
select version();

sql
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.33    |
+-----------+
1 row in set (0.00 sec)

测试实例都是新初始化的干净实例

clone插件安装

安装插件

sql
install plugin clone soname 'mysql_clone.so';

sql
mysql> install plugin clone soname 'mysql_clone.so';
Query OK, 0 rows affected (0.01 sec)

查看插件状态

sql
select plugin_name, plugin_status from information_schema.plugins where plugin_name = 'clone';

sql
mysql> 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)

克隆

当前测试的注意点:

源端与接收端 的字符集需要一致

大小写配置需要一致

配置尽可能相近

重建主从时注意 UUID server-id不能一样

本地克隆

创建克隆账号

该账号需要backup_admin权限

sql
create user clone_user identified by '123456';
grant backup_admin on *.* to clone_user;
FLUSH PRIVILEGES;
-- 查看是否有backup_admin权限
GRANT USAGE ON *.* TO `clone_user`@`%`

创建clone目录

clone目录属主属组设置为启动mysql服务的用户

bash
mkdir /data/clone_dir
chown mysql:mysql -R /data/clone_dir

bash
bash-4.4# mkdir clone_dir
bash-4.4# chown mysql:mysql -R clone_dir/
bash-4.4# ls -l
drwxr-xr-x. 2 mysql mysql 6 Nov 20 11:51 clone_dir

用clone账号登陆做本地克隆

sql
clone local data directory = '/data/clone_dir/mysql';

启动并检查clone数据目录

克隆后,关闭原来的数据库,将数据目录切换成clone的目录【或拷贝原有的目录到对应的目录】,然后启动MySQL

远程克隆

远程克隆中,源叫做捐赠者,目标叫做接收者,接收者建议保持为空,如果不为空会被清空

在线安装插件【两端都要创建】

sql
install plugin clone soname 'mysql_clone.so';

创建克隆账号【捐赠者创建】

这里的克隆账号需要clone_admin权限,这个权限比捐赠者上的克隆账号多了shutdown权限,克隆完后需要重启数据库,所以非mysqld_safe启动则会报错,但不影响克隆,手动重启数据库即可。

sql
create user clone_user identified by '123456';
grant clone_admin on *.* to clone_user;
FLUSH PRIVILEGES;
-- 查看是否有backup_admin权限
GRANT USAGE ON *.* TO `clone_user`@`%`;
SHOW GRANTS FOR 'clone_user'@'%';

设置捐赠者列表清单【接收者设置】

sql
set global clone_valid_donor_list = '192.168.0.65:3306';

用clone账号登陆做远程克隆【接收者执行】

sql
clone instance from clone_user@'192.168.0.65':3306 identified by '123456';

这里应该会重启,没有重启手动重启即可,重连后查看数据即可

捐赠者和接收者创建复制关系

捐赠者上创建复制账号

sql
create user rpl identified with 'mysql_native_password' by '123';
grant replication slave on *.* to rpl;

接收者设置主从关系

sql
change master to master_host = '192.168.0.65',
master_user = 'rpl',
master_password = '123',
master_port = 3306,
master_auto_position = 1;

启动并检查复制关系

sql
start slave;
show slave status\G;

其他相关小操作

查看克隆过程状态及错误

sql
SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;

查看克隆步骤

sql
select 
stage,
state,
cast(begin_time as DATETIME) as "START TIME",
cast(end_time as DATETIME) as "FINISH TIME",
lpad(sys.format_time(power(10,12) * (unix_timestamp(end_time) - unix_timestamp(begin_time))), 10, ' ') as DURATION,
lpad(concat(format(round(estimate/1024/1024,0), 0), "MB"), 16, ' ') as "Estimate",
case when begin_time is NULL then LPAD('%0', 7, ' ')
when estimate > 0 then
lpad(concat(round(data*100/estimate, 0), "%"), 7, ' ')
when end_time is NULL then lpad('0%', 7, ' ')
else lpad('100%', 7, ' ')
end as "Done(%)"
from performance_schema.clone_progress;

查看克隆次数

只能看本地克隆次数,该命令记录clone命令执行次数 远程克隆,在接收者上执行,clone成功后服务重启,这个值会被置零

sql
show global status like 'Com_clone';

停止克隆

直接kill克隆线程即可

错误处理

3862
sql
ERROR 3862 (HY000): Clone Donor Error: 3957 : Clone needs max_allowed_packet value to be 2097152 or more. Current value is 1048576.
sql
-- 查看 max_allowed_packet 值
SHOW VARIABLES LIKE 'max_allowed_packet';

-- 临时设置 max_allowed_packet 值
SET GLOBAL max_allowed_packet = 2 * 1024 * 1024;

-- 配置文件my.cnf配置 max_allowed_packet 值
[mysqld]
max_allowed_packet = 2M
3868
sql
ERROR 3868 (HY000): Clone Configuration collation_server: Donor value: utf8mb4_general_ci is different from Recipient value: utf8mb4_0900_ai_ci.
ini
-- 配置文件my.cnf配置 字符集
[mysqld]
collation-server=utf8mb4_general_ci
3869
sql
ERROR 3869 (HY000): Clone system configuration: xxx.xxx.xxx.xxx:3306 is not found in clone_valid_donor_list:
sql
set global clone_valid_donor_list = 'xxx.xxx.xxx.xxx:3306';
clone instance from clone_user@'xxx.xxx.xxx.xxx':3306 identified by 'password';

xxx.xxx.xxx.xxx:标识服务端地址

主库配置

sql
-- 安装插件
install plugin clone soname 'mysql_clone.so';
-- 查看插件状态
select plugin_name, plugin_status from information_schema.plugins where plugin_name = 'clone';
-- 创建clone用户
create user clone_user identified by '123456';
-- 远程的话需要开启远程'%'
create user clone_user@'%' identified by '123456'; 
-- 基于clone用户clone_admin权限
grant clone_admin on *.* to clone_user;
-- 刷新权限
flush privileges;
-- 创建同步用户
create user rpl identified with 'mysql_native_password' by '123';
-- 给予复制数据的权限
grant replication slave on *.* to rpl;
-- 查看克隆过程状态及错误
SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;
-- 查询同步后的数据位置
select binlog_file,binlog_position from performance_schema.clone_status;
-- 查询gtid标识
select @@global.gtid_executed;
-- 当检测到可能的 GTID 一致性问题时,记录警告信息,但不阻止操作。
set global ENFORCE_GTID_CONSISTENCY = WARN;
/**
* OFF:不强制执行 GTID 一致性要求。这可能会导致数据不一致,因此通常不推荐使用
* WARN:当检测到可能的 GTID 一致性问题时,记录警告信息,但不阻止操作。这允许你在不中断服务的情况下监控潜在的问题
* ON:强制执行 GTID 一致性要求。如果检测到问题,MySQL 将阻止操作并返回错误。这是确保数据一致性的最严格设置
* ERROR_FOR_EXPLICIT_GTIDS(在某些 MySQL 版本中可用):对于显式指定的 GTID(例如,在 START SLAVE UNTIL GTID 语句中),强制执行 GTID 一致性要求,并返回错误;对于其他情况,记录警告信息。
**/
set global ENFORCE_GTID_CONSISTENCY = ON;
-- 在 OFF_PERMISSIVE 模式下,MySQL 服务器仍然可以接收基于 GTID 的事务(如果它们是通过复制从其他服务器传来的),但是它不会为本地发起的事务生成 GTID。这意味着,虽然服务器可以处理 GTID 事务,但它不会自己创建它们。
set global GTID_MODE = OFF_PERMISSIVE;
-- 在 OFF_PERMISSIVE 模式下,MySQL 服务器可以接收并处理来自其他服务器的基于 GTID 的事务,但它不会为本地事务生成 GTID。
-- 这允许你在现有的基于语句(SBR)或基于行(RBR)的复制环境中继续使用服务器,同时开始配置和测试基于 GTID 的复制。
set global GTID_MODE = ON_PERMISSIVE;
-- 指示当前有多少个事务在没有全局事务标识符(GTID)的情况下正在执行
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
-- 查看从服务器的状态
show slave status\G;
-- 要求所有事务都使用 GTID,并且复制将基于 GTID 而不是传统的基于二进制日志位置的方式来进行。
set global GTID_MODE = ON;
-- 查看克隆步骤
select 
stage,
state,
cast(begin_time as DATETIME) as "START TIME",
cast(end_time as DATETIME) as "FINISH TIME",
lpad(sys.format_time(power(10,12) * (unix_timestamp(end_time) - unix_timestamp(begin_time))), 10, ' ') as DURATION,
lpad(concat(format(round(estimate/1024/1024,0), 0), "MB"), 16, ' ') as "Estimate",
case when begin_time is NULL then LPAD('%0', 7, ' ')
when estimate > 0 then
lpad(concat(round(data*100/estimate, 0), "%"), 7, ' ')
when end_time is NULL then lpad('0%', 7, ' ')
else lpad('100%', 7, ' ')
end as "Done(%)"
from performance_schema.clone_progress;
-- 查看克隆次数
show global status like 'Com_clone';
-- 显示与服务器 UUID 相关的系统变量
show variables like '%server_uuid%';

从库配置

sql
-- 安装插件
install plugin clone soname 'mysql_clone.so';
-- 创建clone用户及授权
create user clone_user identified by '123456';
grant clone_admin on *.* to clone_user;
-- 设置捐赠者列表清单
set global clone_valid_donor_list = '192.168.207.131:3306';
-- 用clone账号登陆做远程克隆
clone instance from clone_user@'192.168.207.131':3306 identified by '123456';
-- 查看克隆过程状态及错误
SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;
-- 查询同步后的数据位置
select binlog_file,binlog_position from performance_schema.clone_status;
-- 查询gtid标识
select @@global.gtid_executed;
-- 调整连接主服务器的复制参数
change master to master_host = '192.168.207.131',master_user = 'rpl',master_password = '123',master_port = 3306,master_auto_position = 1;
-- 启动主从同步
start slave;
-- 查看从服务器的状态
show slave status\G;
-- 查看克隆步骤
select 
stage,
state,
cast(begin_time as DATETIME) as "START TIME",
cast(end_time as DATETIME) as "FINISH TIME",
lpad(sys.format_time(power(10,12) * (unix_timestamp(end_time) - unix_timestamp(begin_time))), 10, ' ') as DURATION,
lpad(concat(format(round(estimate/1024/1024,0), 0), "MB"), 16, ' ') as "Estimate",
case when begin_time is NULL then LPAD('%0', 7, ' ')
when estimate > 0 then
lpad(concat(round(data*100/estimate, 0), "%"), 7, ' ')
when end_time is NULL then lpad('0%', 7, ' ')
else lpad('100%', 7, ' ')
end as "Done(%)"
from performance_schema.clone_progress;
-- 查看克隆次数
show global status like 'Com_clone';
-- 显示与服务器 UUID 相关的系统变量
show variables like '%server_uuid%';
-- 查询服务器配置相关的系统变量
show variables like '%server%';