MySQL8.0.17推出了一个重量级的功能:clone plugin。允许用户可以将当前实例进行本地或者远程的clone操作。适用于整个实例快速备份和mgr新成员加入。
clone的定义:是把存储在InnoDB中的schema(database)、table(表)、tablespaces(表空间)和data dictionary metadata(数据字典元数据)的数据,进行在线物理快照。
有几次看其他同仁介绍,讲到clone能替代Percona xtrabackup。
那下面来了解一下。
1.1. 加载
clone也是跟 其他plugin插件方式一样,存在于mysql/lib/plugin目录下
需要在配置my.cnf启动加载项
##配置my.cnf 8.0.20版本试了都不行,是个坑,看来后续版本会修复 [mysqld] plugin-load-add=mysql_clone.so clone=FORCE_PLUS_PERMANENT ##启动加载,是可以的 mysqld_safe --defaults-file=/etc/my.cnf --plugin-load-add=mysql_clone.so --user=mysql &
复制
备注:这里FORCE_PLUS_PERMANENT保护机制,启动时加载插件并防止它在运行时被删除
命令行加载跟靠谱:
##加载 mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so'; Query OK, 0 rows affected (0.01 sec) ##卸载命令 mysql> UNINSTALL PLUGIN clone; Query OK, 0 rows affected (0.01 sec) ##查看 mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
复制
备注:加载介绍,抽空最好看下官网。 https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-installation.html
1.2. 本地clone
本地clone操作从MySQL服务器实例clone数据,其中clone操作被初始化到运行MySQL服务器实例的同一个服务器或节点上的目录。
执行clone本地数据目录语句需要BACKUP_ADMIN特权。
mysql> CREATE USER 'clone_user'@'%' identified by '123456'; Query OK, 0 rows affected (0.01 sec) mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user'@'%' ; Query OK, 0 rows affected (0.01 sec)
复制
用backup账号登录登录进行clone操作
##文件夹权限,必须要赋予mysql所有权要不会报错 [root@ens8 backup]# chown -R mysql:mysql /opt/backup/20200520 ##backup权限登录只能看到 infomation库 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ ##bak目录不能存在,如存在会提示database exists错误 mysql> clone LOCAL DATA DIRECTORY = '/opt/backup/20200520/bak'; Query OK, 0 rows affected (0.58 sec)
复制
真个过程很简单,查看备份文件:
备注:
- 少了information_schema, db2文件夹 ,生产上db2只是空的库,无表。
- 以下文件不会被clone:socket、pid-file、tmpdir、log-error、slow_query_log_file、log-bin、relay-log
1.3. 恢复
#清空datadir目录,把备份出来的clone_dir文件拷贝datadir目录下,还得touch一个 错误日志 [root@ens8 mysql]# cp -r /opt/backup/20200520/bak /opt/data8.1/mysql [root@ens8 mysql]# touch /opt/data8.1/logs/mysql_err.log [root@ens8 mysql]# chow -R mysql:mysql [root@ens8 mysql]# mysqld_safe --defaults-file=/etc/clone.cnf --user=mysql &
复制
clone库登录确认:
数据库显示正常,master status也正常(原主库gtid信息也包含)
快速搭建从库:试过多次正常很稳,说明clone出来的文件一致性做的很好。
mysql> change master to -> master_host = '192.168.244.129', -> master_port = 3380, -> master_user = 'repl', -> master_password = '123456', -> master_auto_position=1;
复制
备注;
在clone数据时,将创建以下目录和文件供内部使用。千万不要修改。
- #clone:包含clone操作使用的内部clone文件。在数据被clone到的目录中创建。
- #ib_archive:包含内部归档的日志文件,在操作期间在提供者上归档。
- *.#clone files:在远程clone操作替换现有数据目录时在收件人上创建的临时数据文件。
1.4. 远程clone
远程clone操作涉及启动clone操作的本地MySQL服务器实例(“recipient”)和源数据所在的远程MySQL服务器实例(“donor”)。当在recipient上启动远程clone操作时,clone数据通过网络从发送方传输到接收方。默认情况下,远程clone操作删除recipient数据目录中的数据,并用clone的数据替换它。可以选择将数据复制到recipient上的另一个目录,以避免删除现有数据。
本地clone操作的数据与远程clone操作的数据没有区别。这两个操作clone相同的数据。
clone plugin支持复制。除了clone数据之外,clone操作还从donor提取和传输复制坐标,并将它们应用于recipient,这使得可以使用clone plugin来提供组复制成员和复制从属节点。与复制大量事务相比,使用clone plugin进行供应要快得多,效率也高得多。组复制成员还可以配置为使用clone插件作为另一种恢复方法,以便成员自动选择从种子成员检索组数据的最有效方法。clone plugin支持加密的和页面压缩的数据。
1.4.1 语法
clone INSTANCE FROM 'user'@'host':port IDENTIFIED BY 'password' [DATA DIRECTORY [=] 'clone_dir'] [REQUIRE [NO] SSL];
复制
语法里指定: ip,端口,用户,密码,目录 即可。
1.4.2 13个限制条件:
donor:节点处于为新节点准备或传输集群全量数据状态,就是源端
recipient:需要复制的节点,就是目标端
- 1.clone插件必须在发送方(donor)和接收方(recipient)的MySQL服务器实例上都是活动的
- 2.权限:
源端Donor登录的用户需要BACKUP_ADMIN特权来访问和传输来自clone服务器的数据,并在操作期间阻塞DDL。
目标端Recipient用户需要clone_ADMIN特权来替换收件人数据,在操作期间阻塞DDL,并自动重新启动服务器。clone_ADMIN特权隐式地包括BACKUP_ADMIN和SHUTDOWN特权。 - 3.版本一致:donor和recipient必须拥有相同的MySQL服务器版本。MYSQL 8.0.17及更高版本支持clone插件。
- 4.recipient必须有足够的磁盘空间来存放clone数据。
- 5.SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES;识别出来的内容才会被clone
- 6.相同的MySQL服务器字符集和排序规则
- 7.innodb_page_size和innodb_data_file_path设置 必须相同
- 8.clone加密或页面压缩的数据,则donor和replicat必须具有相同的文件系统块大小。
- 9.ssl, 秘钥机制必须是一样的
- 10.recipient里设置clone_valid_donor_list 源库的信息
- 11.一次只允许一个clone操作
- 12.clone插件以1MB包和元数据的形式传输数据。因此,对于recipient和donor的MySQL服务器实例,最小需要的max_allowed_packet值是2MB。max_allowed_packet值小于2MB会导致错误。
- 13.Undo表空间clone期间,不得变更,MySQL 8.0.18开始,如果在clone操作期间遇到重复的undo表空间文件名,就会报告错误。
1.4.3 准备工作
donor原用之前的库,recipient加载插件
##加载组件 mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so'; Query OK, 0 rows affected (0.02 sec) mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone'; +-------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +-------------+---------------+ | clone | ACTIVE | +-------------+---------------+ ##用户创建BACKUP_ADMIN ,clone_ADMIN权限 mysql> CREATE USER 'clone_user'@'%' identified by '123456'; Query OK, 0 rows affected (0.01 sec) mysql> GRANT BACKUP_ADMIN ,clone_ADMIN ON *.* TO 'clone_user'@'%' ; Query OK, 0 rows affected (0.01 sec) ##源端ip信息 mysql> SET GLOBAL clone_valid_donor_list = "192.168.244.129:3380"; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE 'clone_valid_donor_list'; +------------------------+----------------------+ | Variable_name | Value | +------------------------+----------------------+ | clone_valid_donor_list | 192.168.244.129:3380 | +------------------------+----------------------+
复制
1.4.4 开始clone
recipient服务器用clone_user登录,执行clone覆盖本地数据
##clone mysql> clone INSTANCE FROM 'clone_user'@'192.168.244.129':3380 IDENTIFIED BY '123456'; Query OK, 0 rows affected (1.76 sec) mysql> Restarting mysqld... 2020-05-22T15:41:51.659583Z mysqld_safe Number of processes running now: 0 2020-05-22T15:41:51.666882Z mysqld_safe mysqld restarted
复制
指定目录:
mysql>clone INSTANCE FROM 'clone_user'@'192.168.244.129':3380 IDENTIFIED BY '123456' DATA DIRECTORY= '/opt/backup/20200520/bak02';
复制
只是进行数据clone没有覆盖和重新启动数据库服务。需要手动配置路径才能使用clone数据。剩下的就是本地clone的后续恢复操作方式。
因为数据量少,所以非常快。如果clone的数据量很大,这个命令通常会耗费很长时间。
1.4.5 查看clone状态
这里有两种方式,但发现还是欠缺,特别是error记录基本也没有。
1)performance_schema下提供了两张表: clone_status,clone_progress来监控执行状态和情况
具体表字段说明:
-
clone_status
ID: 当前MySQL服务器实例中的唯一clone操作标识符
PID: 执行clone操作的会话的进程列表ID
STATE: clone操作的当前状态值包括未启动、正在进行、已完成和失败
(Not Started, In Progress, Completed, and Failed)
BEGIN_TIME: 开始时间
END_TIME: 结束时间
SOURCE: 源端服务器信息
DESTINATION: 目标端目录
ERROR_NO: 失败 报错编号
ERROR_MESSAGE: 失败报错信息
BINLOG_FILE: 复制数据到的二进制日志文件的名称
BINLOG_POSITION: 复制数据到的二进制日志的位置
GTID_EXECUTED: 最后一个clone事务的GTID值 -
clone_progress
ID: 当前MySQL服务器实例中的唯一clone操作标识符
STAGE: 阶段包括删除数据、文件复制、PAGE_COPY、REDO_COPY、FILE_SYNC、重新启动和恢复
STATE: clone阶段的当前状态状态包括未启动、正在进行和已完成
Not Started, In Progress, Completed
BEGIN_TIME: 开始时间
END_TIME: 结束时间
THREADS: 阶段中使用的并发线程数
ESTIMATE: 当前阶段的估计数据量,以字节为单位
DATA: 当前状态下传输的数据量,以字节为单位
NETWORK: 当前状态下传输的网络数据量,以字节为单位
DATA_SPEED: 当前数据传输的实际速度,以每秒字节为单位
这个值可能与clone_max_data_bandwidth定义的请求最大数据传输速率不同
NETWORK_SPEED: 当前网络传输的速度,以每秒字节为单位
备注:clone_progress表中,可以看到clone过程分为这么几个阶段:DROP DATA, FILE COPY, PAGE COPY, REDO COPY, FILE SYNC, RESTART, RECOVERY,这个对于了解现阶段非常有用。
2)通过performance_schema.setup_instruments参看执行情况
mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'stage/innodb/clone%'; mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%'; mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current WHERE EVENT_NAME LIKE 'stage/innodb/clone%'; +--------------------------------+----------------+----------------+ | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | +--------------------------------+----------------+----------------+ | stage/innodb/clone (redo copy) | 1 | 1 | +--------------------------------+----------------+----------------+ mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM events_stages_history WHERE EVENT_NAME LIKE 'stage/innodb/clone%'; +--------------------------------+----------------+----------------+ | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | +--------------------------------+----------------+----------------+ | stage/innodb/clone (file copy) | 301 | 301 | | stage/innodb/clone (page copy) | 0 | 0 | | stage/innodb/clone (redo copy) | 1 | 1 | +--------------------------------+----------------+----------------+ mysql> SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE WHERE NAME LIKE '%clone%'; +----------------------------------------------+---------+ | NAME | ENABLED | +----------------------------------------------+---------+ | wait/synch/mutex/innodb/clone_snapshot_mutex | NO | | wait/synch/mutex/innodb/clone_sys_mutex | NO | | wait/synch/mutex/innodb/clone_task_mutex | NO | | wait/io/file/innodb/innodb_clone_file | YES | | stage/innodb/clone (file copy) | YES | | stage/innodb/clone (redo copy) | YES | | stage/innodb/clone (page copy) | YES | | statement/abstract/clone | YES | | statement/clone/local | YES | | statement/clone/client | YES | | statement/clone/server | YES | | memory/innodb/clone | YES | | memory/clone/data | YES | +----------------------------------------------+---------+
复制
性能模式语句事件跟踪语句执行:
- statement/abstract/clone: 跟踪任何clone操作的语句事件,然后将其分类为本地、客户端或服务器操作类型。
- statement/clone/local: 跟踪本地clone操作的clone语句事件;在执行clone本地语句时生成。
- statement/clone/client: 跟踪发生在接收方MySQL服务器实例上的远程clone语句事件;在收件人上执行clone实例语句时生成。
- statement/clone/server: 跟踪远程cloneMySQL服务器实例上发生的语句事件;在收件人上执行clone实例语句时生成。
详细说明:https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-monitoring.html
3)mysql_error里记录信息
只有两行,其他没有了,确实需要官方改善一下。
因为有时候performance库会存在hang住的情况。
1.4.6 停止clone操作
通过performance_schema.clone_status表的PID信息,之后使用 KILL QUERY processlist_id 语句停止clone操作
1.5. clone参数
到目前为止已提供11个参数配合clone 一起使用。变量是在执行clone操作的MySQL服务器实例上配置。建议源目标库都设置,都是动态参数。
- 1.clone-autotune-concurrency:
默认值:Yes, 配置对象:recipient,
说明:为远程clone操作启用线程的动态生成。该设置仅适用于接收MySQL服务器实例。clone_max_concurrency变量定义可以派生的最大线程数 - 2.clone_max_concurrency:
默认值:16, 范围:1~128, 配置对象:recipient,
说明:定义远程clone操作的最大并发线程数。默认值是16。更多的线程可以提高clone性能,但也会减少允许同时进行的客户端连接的数量,这会影响现有客户端连接的性能 - 3.clone_max_data_bandwidth:
默认值:0, 范围:0~1048576, 配置对象:recipient,
说明: 定义远程clone操作每秒的最大数据传输速率,单位为mebibytes (MiB)。此变量有助于管理clone操作的性能影响。只有当供体磁盘I/O带宽达到饱和,影响性能时,才应该设置限制 - 4.clone_max_network_bandwidth:
默认值:0 范围:0~1048576 配置对象:recipient
说明:指定远程clone操作每秒的最大近似网络传输速率(以mebibytes (MiB)为单位) - 5.clone_valid_donor_list:
配置对象:recipient
说明:定义远程clone操作的有效主机地址 - 6.clone-enable-compression:
默认值:OFF 配置对象:donor,recipient
说明:允许在远程clone操作期间压缩网络层的数据。压缩以CPU为代价节省网络带宽。启用压缩可以提高数据传输速率 - 7.clone-ddl-timeout:
默认值:0 范围:0~2592000 配置对象:donor,recipient
说明:执行clone操作时等待备份锁的时间(以秒为单位)。此设置同时应用于发送方和接收方MySQL服务器实例。值0表示clone操作不需要备份锁。在这种情况下,如果同时尝试DDL操作,操作将失败并出现错误 - 8.clone-buffer-size:
默认值:4M 范围:1048576~268435456 配置对象:donor,recipient
说明:默认值是4兆字节(MiB)。较大的缓冲区大小可能允许I/O设备驱动程序并行地获取数据,这可以提高clone性能。 - 9.clone_ssl_ca:
配置对象:recipient
说明:ca证书 - 10.clone-ssl-cert:
配置对象:recipient
说明:指定公钥证书的路径 - 11.clone_ssl_key:
配置对象:recipient
说明:指定私钥文件的路径
1.6. 问题点
- 对网络的负载,会不会存在传输上clone占据这个网络带宽的的问题,虽然有参数设置,但毕竟需要时间来打磨。特别是现在有些企业mysql单库能到1T级别数据量的情况下。
- clone是否会穷住线程, mysql线程池问题还是比较多。
- clone单个库备份,单个表暂时无法支持,希望能提供这样的功能。毕竟有多源复制功能
- clone功能会删除目标MySQL实例上的所有数据。之前做好备份。
- clone的日志功能 方面需要改善
1.7. 总结
个人对于体验来说,目前认为还不能替代xtrabackup的功能,只能说各有千秋。
虽然mgr环境中,初始化是clone实现的,但就上面提到的问题点,功能点,大数据量传递稳定性,日志记录等方面,还不完善。
这里clone实现的亮点是使用了Page Tracking和Redo Archiving功能,xtrabackup是基于Redo Archiving功能,这部分可以了解一下,值得学习。
8.0实际环境中,应该两手兼备xtrabackup & clone,也希望xtrabackup基于clone开发新的功能,精益求精,竞争中才有进步。
参考:
https://dev.mysql.com/doc/refman/8.0/en/clone-plugin.html
https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-replication.html
https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-remote.html
https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-monitoring.html