1 数据库克隆概念介绍
在数据库MySQL 8.0(8.0.17+)版本中,引⼊了数据库的克隆功能,主要是借助clone-plugin实现的,是对数据⻚ 底层克隆;
克隆的数据是InnoDB存储引擎中的物理快照信息,包括schemas, tables, tablespaces, and data dictionary metadata;
在数据库中出现克隆功能,主要是为了满⾜⽬前云原⽣的技术应⽤场景,同时也是为了海量数据备份⽽诞⽣的;
在数据库中实现克隆功能应⽤有两种⽅式:
1.1 本地克隆(Local Cloning):
启动克隆操作的MySQL数据库服务器实例中的数据,将会克隆到同服务器或同节点上的⼀个⽬录⾥;
1.2 远程克隆(Remote Cloning):
默认情况下,远程克隆操作会删除接受者(recipient)数据⽬录中的数据,并将其替换为捐赠者(donor)的克隆 数据;
也可以将数据克隆到接受者的其他⽬录中,以避免删除现有数据;(属于可选操作);
主要⽤于实现数据远程的快速热迁移操作,在迁移过程中,除了DDL操作情况,其他操作都不会出现阻塞情况;
还可以利⽤远程克隆技术,实现快速构建数据库的主从架构环境,实现主从数据信息快速复制同步;
2 数据库克隆原理
在进⾏数据库克隆操作时,会经历⼏个重要的过程或步骤:
2.1 Page copy:
在进⾏数据⻚复制操作时,会涉及到两个操作动作:
开启redo archiving功能,从当前点开始存储新增的redo_log,这样从当前位置点开始所有的增量修改都不会丢 失;
同时上⼀步在page track的page被发送到⽬标端,确保当前位置点之前所有做的变更⼀定发送到⽬标端;
关于redo archiving实际上这是官⽅早就存在的功能,主要⽤于官⽅的企业级备份⼯具,clone利⽤了该特性来维 持记录增量产⽣的redo在开始克隆前会做⼀次checkpoint;
对于redo archiving功能应⽤,会开启⼀个后台线程log_archiver_thread()来做⽇志归档;
当有新的写⼊时(notify_about_advanced_write_lsn),也会通知线程去进⾏归档,当arch_log_sys处于活跃状态 时,
线程会控制⽇志写⼊以避免未归档的⽇志被覆盖(log_write_wait_on_archiver),注意如果log_write等待时间过⻓ 的话,archive任务会被中断掉;
2.2 Redo copy:
停⽌redo archiving功能,所有归档的⽇志被发送到⽬标端,这些⽇志包含了从page copy阶段开始到现在的所有 ⽇志;
另外可能还需要记下当前的复制点,例如:最后⼀个事务提交时的binlog位置点或者gtid信息,在系统⻚中可以找 到;
2.3 Done:
⽬标端重启实例,通过crash recovery将redo log应⽤上去;
克隆原理过程分析参考链接:https://zhuanlan.zhihu.com/p/437760913
说明:整个克隆过程都会以事件信息记录,可以很清晰的看到克隆的流程,如果克隆过程中断,也会以追加 ⽅式进⾏继续克隆;
在进⾏克隆功能应⽤时,也是存在⼀些限制性操作的:(结合官⽅列出的限制)
对于MySQL 8.0.27之前版本,在进⾏克隆操作期间,是不允许在捐赠者和接受者上进⾏DDL操作,包括:
truncate table操作;
对于MySQL 8.0.27之后版本,在捐赠者上默认允许并发DDL操作,对于捐赠者上并发DDL的⽀持由clone_block_DDL变量控制;
对于不同版本的MySQL数据库实例之间,是不能进⾏克隆操作的。对于捐赠者和接受者必须是确切相同数据 库服务版本;
例如:你不能克隆数据在between MySQL 5.7 and MySQL 8.0, or between MySQL 8.0.19 and MySQL8.0.20;
这个克隆功能只⽀持在数据库8.0.17版本或之后的版本
参考官⽅链接说明:https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-limitations.html
3 数据库克隆功能实践
3.1 实现本地克隆操作过程:
克隆需求:实现快速创建和源数据库服务⼀模⼀样的多实例服务程序;
克隆操作步骤01:加载克隆插件信息
# 进⾏克隆插件加载配置
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
或者
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT
# 查看克隆插件加载情况
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)
克隆操作步骤02:创建克隆专⽤⽤户
mysql> create user clone_user@'%' identified by 'password';
mysql> grant backup_admin on *.* to 'clone_user';
-- backup_admin权限是mysql 8.0才有的备份锁的权限;
克隆操作步骤03:进⾏本地克隆操作
[root@xiaoQ-01 ~]# mkdir -p /data/test
[root@xiaoQ-01 ~]# chown -R mysql.mysql /data/
[root@xiaoQ-01 ~]# mysql -uclone_user -ppassword
mysql> clone local data directory = '/data/test/clonedir';
-- 完成本地数据库⽬录的克隆操作
克隆操作步骤04:观测本地克隆状态
mysql> select stage,state,end_time from performance_schema.clone_progress;
+---------------+----------------+-----------------------------------+
| stage | state | end_time |
+---------------+----------------+-----------------------------------+
| DROP DATA | Completed | 2022-11-28 01:11:17.715901 |
| FILE COPY | Completed | 2022-11-28 01:11:17.752819 |
| PAGE COPY | Completed | 2022-11-28 01:11:17.756830 |
| REDO COPY | Completed | 2022-11-28 01:11:17.757802 |
| FILE SYNC | Completed | 2022-11-28 01:11:17.912679 |
| RESTART | Not Started | NULL |
| RECOVERY | Not Started | NULL |
+---------------+----------------+-----------------------------------+
7 rows in set (0.00 sec)
-- 当克隆数据量⽐较⼤的时候,可以使⽤此SQL语句进⾏克隆状态查看
克隆操作步骤05:实现克隆⽇志观测
mysql> set global log_error_verbosity=3;
[root@xiaoQ-01 ~]# tail -f db01.err
mysql> clone local data directory = '/data/test/clonedir'
克隆操作步骤06:启动运⾏克隆实例
[root@xiaoQ-01 ~]# mysqld_safe --datadir=/data/test/clonedir --port=3333 --
socket=/tmp/mysql3333.sock --user=mysql --mysqlx=off &
[root@xiaoQ-01 ~]# netstat -lntup|grep 3333
tcp6 0 0 :::3333 :::* LISTEN
52674/mysqld
3.2 实现远程克隆操作过程:
在进⾏实现远程克隆操作步骤之前,可以利⽤虚拟软件再次克隆出⼀台新的数据库8.0版本的服务器主机;
克隆操作步骤01:克隆操作环境准备
# 在克隆接收者主机上清理数据库服务环境:
[root@xiaoQ-02 ~]# pkill mysqld
[root@xiaoQ-02 ~]# rm -rf /data/3306/data/*
[root@xiaoQ-02 ~]# rm -rf /data/3306/binlog/*
[root@xiaoQ-02 ~]# rm -rf /data/3306/logs/*
# 在克隆接收者主机上进⾏实例初始化操作:
[root@xiaoQ-02 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql
--datadir=/data/3306/data
[root@xiaoQ-02 ~]# vim /etc/my.cnf
[mysqld]
server_id=2
-- 修改克隆接收者主机上的server_id的配置信息
# 在克隆接收者主机上进⾏实例的运⾏操作:
[root@xiaoQ-02 ~]# /etc/init.d/mysqld start
克隆操作步骤02:加载克隆插件信息
# 进⾏克隆插件加载配置
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
或者
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT
-- 克隆插件信息需要在克隆主机的捐赠者和接受者上都进⾏安装
# 查看克隆插件加载情况
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)
-- 克隆插件信息需要在克隆主机的捐赠者和接受者上都进⾏安装后确认
克隆操作步骤03:创建克隆专⽤⽤户
# 在克隆捐赠者主机上进⾏授权(数据库01主机上设置)
mysql> create user test_jz@'%' identified by 'password';
mysql> grant backup_admin on *.* to test_jz@'%' ;
-- backup_admin权限是mysql 8.0才有的备份锁的权限;
# 在克隆接收者主机上进⾏授权(数据库02主机上设置)
mysql> create user test_js@'%' identified by 'password';
mysql> grant clone_admin on *.* to test_js@'%' ;
-- clone_admin权限是mysql 8.0才有的克隆同步数据的权限;
说明:可以在克隆捐赠者主机上和接收者主机上均创建两个⽤户信息,防⽌克隆同步数据后,接收者主机上
不再含有接收⽤户信息;
克隆操作步骤04:进⾏远程克隆操作
# 在克隆接收者主机上进⾏设置
mysql> set global clone_valid_donor_list='192.168.30.101:3306';
-- 设置克隆同步数据的信任列表
# 在克隆接收者主机上进⾏克隆
[root@xiaoq-02 ~]# mysql -utest_js -ppassword -h192.168.30.102 -P3306
mysql> clone instance from test_jz@'192.168.30.101':3306 identified by 'password';
-- 在接收者主机上实现远程克隆操作
克隆操作步骤05:观测本地克隆状态
mysql> select stage,state,end_time from performance_schema.clone_progress;
+---------------+----------------+-----------------------------------+
| stage | state | end_time |
+---------------+----------------+-----------------------------------+
| DROP DATA | Completed | 2022-11-29 00:15:34.002378 |
| FILE COPY | Completed | 2022-11-29 00:15:35.218397 |
| PAGE COPY | Completed | 2022-11-29 00:15:35.225659 |
| REDO COPY | Completed | 2022-11-29 00:15:35.229777 || FILE SYNC | Completed | 2022-11-29 00:15:35.773431 |
| RESTART | Completed | 2022-11-29 00:15:39.189607 |
| RECOVERY | Completed | 2022-11-29 00:15:39.978301 |
+---------------+----------------+-----------------------------------+
7 rows in set (0.00 sec)
-- 当克隆数据量⽐较⼤的时候,可以使⽤此SQL语句进⾏克隆状态查看,在克隆接收者主机上进⾏查看
mysql> show databases;
-- 此时克隆接收者主机上查看到的数据信息,与克隆捐赠者主机上查看到的数据信息⼀致,即远程克隆操作完成