作者介绍
陈臣,甲骨文MySQL首席解决方案工程师,公众号《MySQL实战》作者,有大规模的MySQL,Redis,MongoDB,ES的管理和维护经验,擅长MySQL数据库的性能优化及日常操作的原理剖析。
Clone Plugin(克隆插件)是MySQL 8.0.17引入的一个重大特性,实现该特性主要是为Group Replication服务。在Group Replication中,如果要添加一个新的节点,这个节点差异数据的补齐是通过分布式恢复(Distributed Recovery)来实现的。
在MySQL 8.0.17之前,只支持一种恢复方式,即Binlog。如果新节点需要的Binlog在集群中不存在,那么就只能借助于备份工具先做个全量数据的备份恢复,再通过分布式恢复同步增量数据。
这种方式虽然也能达到添加节点的目的,但总归是要借助外部工具,相对来说有一定的使用门槛和工作量。
有了Clone Plugin,只用一条命令,我们就能很方便地添加一个新的节点,无论是在Group Replication还是普通的主从环境中。
一、Clone Plugin的安装
Clone Plugin可通过以下两种方式安装:
1)配置文件中指定
[mysqld]
plugin-load-add=mysql_clone.so
2)动态加载
mysql> install plugin clone soname 'mysql_clone.so';
执行show plugins查看插件是否安装成功。
mysql> show plugins;
+---------------------------------+----------+--------------------+----------------+---------+
| Name | Status | Type | Library | License |
+---------------------------------+----------+--------------------+----------------+---------+
...
| clone | ACTIVE | CLONE | mysql_clone.so | GPL |
...
Status为ACTIVE代表插件加载成功。
二、Clone Plugin的使用
Clone Plugin支持两种克隆方式:本地克隆和远程克隆。这两种克隆方式的使用方法如下。
1、本地克隆
本地克隆的原理图如下所示,它可将本地MySQL实例中的数据拷贝到本地服务器的一个目录中。本地克隆只能在实例本地发起。
本地克隆命令的语法如下:
CLONE LOCAL DATA DIRECTORY [=] 'clone_dir';
下面我们看下具体的使用步骤:
1)创建克隆用户
mysql> create user 'clone_user'@'%' identified by 'clone_pass';
mysql> grant backup_admin on *.* to 'clone_user'@'%';
这里的backup_admin是克隆操作必需权限,它允许用户执行LOCK INSTANCE FOR BACKUP命令。
2)创建克隆目录
# mkdir -p /data/backup
# chown -R mysql.mysql /data/backup/
3)执行本地克隆操作
# mysql -uclone_user -pclone_pass
mysql> clone local data directory='/data/backup/3307';
这里的/data/backup/3307是克隆目录,它需满足以下几点要求:
4)查看克隆目录的内容
# ll /data/backup/3307
total 200644
drwxr-x--- 2 mysql mysql 89 Oct 23 22:09 #clone
-rw-r----- 1 mysql mysql 4049 Oct 23 22:09 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 Oct 23 22:09 ibdata1
-rw-r----- 1 mysql mysql 50331648 Oct 23 22:09 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Oct 23 22:09 ib_logfile1
drwxr-x--- 2 mysql mysql 6 Oct 23 22:09 mysql
-rw-r----- 1 mysql mysql 25165824 Oct 23 22:09 mysql.ibd
drwxr-x--- 2 mysql mysql 20 Oct 23 22:09 slowtech
drwxr-x--- 2 mysql mysql 28 Oct 23 22:09 sys
-rw-r----- 1 mysql mysql 33554432 Oct 23 22:09 undo_001
-rw-r----- 1 mysql mysql 16777216 Oct 23 22:09 undo_002
5)可直接基于备份集启动实例
# /usr/local/mysql/bin/mysqld --no-defaults --datadir=/data/backup/3307 --user mysql --port 3307 &
相对于Xtrabackup,Clone Plugin无需Prepare阶段。
2、远程克隆
远程克隆的原理图如下所示,涉及两个实例。其中,被克隆的实例是Donor,接受克隆数据的实例是Recipient。克隆命令需在Recipient上发起。
远程克隆命令的语法如下:
CLONE INSTANCE FROM 'user'@'host':port
IDENTIFIED BY 'password'
[DATA DIRECTORY [=] 'clone_dir']
[REQUIRE [NO] SSL];
其中,
下面我们看看具体的使用步骤:
1)在Donor实例上创建克隆用户,加载Clone Plugin
mysql> create user 'donor_user'@'%' identified by 'donor_pass';
mysql> grant backup_admin on *.* to 'donor_user'@'%';
mysql> install plugin clone soname 'mysql_clone.so';
2)在Recipient实例上创建克隆用户,加载Clone Plugin
mysql> create user 'recipient_user'@'%' identified by 'recipient_pass';
mysql> grant clone_admin on *.* to 'recipient_user'@'%';
mysql> install plugin clone soname 'mysql_clone.so';
这里的clone_admin,隐式含有backup_admin和shutdown(重启实例)权限。
3)在Recipient实例上设置Donor白名单,Recipient只能克隆白名单中的实例
mysql> set global clone_valid_donor_list = '192.168.244.10:3306';
设置该参数需要SYSTEM_VARIABLES_ADMIN权限。
4)在Recipient上发起克隆命令
# mysql -urecipient_user -precipient_pass
mysql> clone instance from 'donor_user'@'192.168.244.10':3306 identified by 'donor_pass';
远程克隆会依次执行以下操作:
# ll /data/mysql/3306/data/
...
-rw-r----- 1 mysql mysql 4049 Oct 24 09:11 ib_buffer_pool
-rw-r----- 1 mysql mysql 4049 Oct 24 10:54 ib_buffer_pool.#clone
-rw-r----- 1 mysql mysql 12582912 Oct 24 10:55 ibdata1
-rw-r----- 1 mysql mysql 12582912 Oct 24 10:55 ibdata1.#clone
...
-rw-r----- 1 mysql mysql 25165824 Oct 24 10:55 mysql.ibd
-rw-r----- 1 mysql mysql 0 Oct 24 10:54 mysql.ibd.#clone
...
三、如何查看克隆操作的进度
查看克隆操作的进度,主要依托于performance_schema中的两张表:clone_status和clone_progress。
下面我们具体看看这两张表的作用及各字段的含义。
1、clone_status
clone_status表记录了克隆操作的状态信息。
mysql> select * from performance_schema.clone_status\G
*************************** 1. row ***************************
ID: 1
PID: 0
STATE: Completed
BEGIN_TIME: 2021-10-24 10:54:35.565
END_TIME: 2021-10-24 10:57:02.382
SOURCE: 192.168.244.10:3306
DESTINATION: LOCAL INSTANCE
ERROR_NO: 0
ERROR_MESSAGE:
BINLOG_FILE: mysql-bin.000004
BINLOG_POSITION: 139952824
GTID_EXECUTED: 453a5124-020e-11ec-8719-000c29f66609:1-17674
1 row in set (0.49 sec)
其中,
2、clone_progress
clone_progress表记录了克隆操作的进度信息。
mysql> select * from performance_schema.clone_progress;
+------+-----------+-----------+----------------------------+----------------------------+---------+-----------+-----------+-----------+------------+---------------+
| ID | STAGE | STATE | BEGIN_TIME | END_TIME | THREADS | ESTIMATE | DATA | NETWORK | DATA_SPEED | NETWORK_SPEED |
+------+-----------+-----------+----------------------------+----------------------------+---------+-----------+-----------+-----------+------------+---------------+
| 1 | DROP DATA | Completed | 2021-10-24 10:54:48.395548 | 2021-10-24 10:54:58.352278 | 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | FILE COPY | Completed | 2021-10-24 10:54:58.352527 | 2021-10-24 10:55:35.908919 | 2 | 616681425 | 616681425 | 616722587 | 0 | 0 |
| 1 | PAGE COPY | Completed | 2021-10-24 10:55:35.958036 | 2021-10-24 10:55:36.670272 | 2 | 7077888 | 7077888 | 7102277 | 0 | 0 |
| 1 | REDO COPY | Completed | 2021-10-24 10:55:36.671544 | 2021-10-24 10:55:37.160154 | 2 | 4372992 | 4372992 | 4373841 | 0 | 0 |
| 1 | FILE SYNC | Completed | 2021-10-24 10:55:37.160412 | 2021-10-24 10:55:39.724808 | 2 | 0 | 0 | 0 | 0 | 0 |
| 1 | RESTART | Completed | 2021-10-24 10:55:39.724808 | 2021-10-24 10:56:55.207049 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | RECOVERY | Completed | 2021-10-24 10:56:55.207049 | 2021-10-24 10:57:02.382057 | 0 | 0 | 0 | 0 | 0 | 0 |
+------+-----------+-----------+----------------------------+----------------------------+---------+-----------+-----------+-----------+------------+---------------+
7 rows in set (0.00 sec)
其中,
四、如何基于克隆数据搭建从库
需要区分GTID复制和基于位置点的复制两种场景。
1、GTID复制
对于GTID复制,无需关心具体的位置点信息,直接设置MASTER_AUTO_POSITION = 1即可。具体命令如下:
mysql> CHANGE MASTER TO MASTER_HOST = 'master_host_name', MASTER_PORT = master_port_num,
...
MASTER_AUTO_POSITION = 1;
mysql> START SLAVE;
在MySQL 5.6,5.7中,通过Xtrabackup搭建从库,在建立复制之前,必须执行SET GLOBAL GTID_PURGED操作。注意,在MySQL 8.0中不要执行。
在Clone Plugin中则无需执行。通过克隆数据启动的实例,GTID_PURGED和GTID_EXECUTED默认已初始正确。
2、基于位置点的复制
具体命令如下:
mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
mysql> CHANGE MASTER TO MASTER_HOST = 'master_host_name', MASTER_PORT = master_port_num,
...
MASTER_LOG_FILE = 'master_log_name',
MASTER_LOG_POS = master_log_pos;
mysql> START SLAVE;
其中,master_host_name,master_port_num是Donor实例的IP和端口。
master_log_name,master_log_pos 分别取自performance_schema.clone_status中的BINLOG_FILE和BINLOG_POSITION。
五、Clone Plugin的实现细节
克隆操作可细分为以下 5 个阶段:
[INIT] ---> [FILE COPY] ---> [PAGE COPY] ---> [REDO COPY] -> [Done]
下面我们看看各个阶段的具体作用:
1)INIT:初始化一个克隆对象。
2)FILE COPY:拷贝数据文件。
在拷贝之前,会将当前CHECKPOINT的LSN记为CLONE START LSN,同时启动Page Tracking。
Page Tracking会跟踪CLONE START LSN之后发生修改的页,记录这些页的tablespace ID和page ID。数据文件拷贝结束后,会将当前CHECKPOINT的LSN记为CLONE FILE END LSN。
3)PAGE COPY:拷贝Page Tracking中记录的页。
在拷贝之前,会基于tablespace ID和page ID对这些页进行排序,避免拷贝过程中的随机读写。同时,开启Redo Archiving。
Redo Archiving会在后台开启一个归档线程将Redo log的内容按Chunk拷贝到归档文件中。通常来说,归档线程的拷贝速度会快于Redo日志的生成速度。即使慢于,在写入新的Redo日志时,也会等待归档线程完成拷贝,不会覆盖还未拷贝的Redo日志。
Page Tracking中的页拷贝完毕后,会获取实例的一致性位置点信息,同时将此时的LSN记为CLONE LSN。
4)REDO COPY:拷贝归档文件中CLONE FILE END LSN与CLONE LSN之间的Redo日志。
5)Done:调用snapshot_end()销毁克隆对象。
六、Clone Plugin的要求和限制
在使用Clone Plugin时,注意以下限制:
1)克隆期间,会阻塞DDL。同样,DDL也会阻塞克隆命令的执行。不过从MySQL 8.0.27开始,克隆命令不会阻塞Donor上的DDL。
2)Clone Plugin不会拷贝Donor的配置参数。
3)Clone Plugin不会拷贝Donor的Binlog。
4)Clone Plugin只会拷贝InnoDB表的数据,对于其它存储引擎的表,只会拷贝表结构。
5)Donor实例中如果有表通过DATA DIRECTORY子句设置了绝对路径,在进行本地克隆时,会提示文件已存在。在进行远程克隆时,绝对路径必须存在且有可写权限。
6)不允许通过MySQL Router连接Donor实例。
7)执行CLONE INSTANCE操作时,指定的Donor端口不能为X Protocol端口。
除此之外,在进行远程克隆时,还有如下要求:
七、Clone Plugin与XtraBackup的异同
1)在实现上,两者都有FILE COPY和REDO COPY阶段,但Clone Plugin比XtraBackup多了一个PAGE COPY阶段。由此带来的好处是,Clone Plugin的恢复速度比XtraBackup快。
2)XtraBackup没有Redo Archiving特性,有可能出现未拷贝的Redo日志被覆盖的情况。
3)GTID下建立复制,Clone Plugin无需额外执行SET GLOBAL GTID_PURGED操作。
八、Clone Plugin的参数解析
1)clone_autotune_concurrency
是否自动调节克隆过程中并发线程数的数量,默认为ON ,此时,最大线程数由参数 clone_max_concurrency控制。若设置为OFF ,并发线程数将是固定的,等于clone_max_concurrency。后者的默认值为16 。
2)clone_block_ddl
克隆过程中是否对Donor实例加备份锁。如果加了,则会阻塞DDL。默认为OFF,不加。该参数是MySQL 8.0.27引入的。
3)clone_delay_after_data_drop
Drop完用户表空间,等待多久才执行数据拷贝操作。引入该参数的初衷是某些文件系统(如 VxFS)是异步释放空间的。如果Drop完用户表空间,就马上执行数据拷贝操作,有可能会因为空间不足而导致克隆失败。该参数是MySQL 8.0.29引入的,默认为0,不等待。
4)clone_buffer_size
本地克隆时,中转缓冲区的大小,默认4M 。缓冲区越大,备份速度越快,相应地,对磁盘IO的压力也越大。
5)clone_ddl_timeout
克隆操作需要获取备份锁。在执行CLONE命令时,如果有DDL正在执行,则CLONE命令会被阻塞,等待获取备份锁(Waiting for backup lock)。等待的最大时长由Recipient实例上的clone_ddl_timeout决定,该参数默认为300s。如果在这个时间内还没获取到备份锁,CLONE命令会失败,且提示ERROR 3862 (HY000): Clone Donor Error: 1205 : Lock wait timeout exceeded; try restarting transaction.
需要注意的是,在执行DDL时,如果有CLONE命令在执行,DDL同样也会因为备份锁而阻塞,只不过,DDL操作的等待时长由lock_wait_timeout决定,该参数默认为31536000s,即365天。
6)clone_donor_timeout_after_network_failure
远程克隆时,如果出现了网络错误,克隆操作不会马上终止,而是会等待一段时间。如果在这个时间内,网络恢复了,操作会继续进行。在MySQL 8.0.24之前,等待时间是固定的5min。从MySQL 8.0.24开始,可通过clone_donor_timeout_after_network_failure设置这个时间,默认是5 min。
7)clone_enable_compression
远程克隆传输数据时,是否开启压缩。默认为OFF。开启压缩能节省网络带宽,但相应地,会增加CPU消耗。
8)clone_max_data_bandwidth
远程克隆时,可允许的最大数据拷贝速率,单位MB/s。默认为0,不限制。如果Donor的磁盘IO存在瓶颈,可通过该参数来限速。
注意,这里限制的只是单个线程的拷贝速率。如果是多个线程并行拷贝,实际最大拷贝速率 = clone_max_data_bandwidth * 线程数。
9)clone_max_network_bandwidth
远程克隆时,可允许的最大网络传输速率,单位MiB/s 。默认为0,不限制。如果网络带宽存在瓶颈,可通过该参数来限速。
10)clone_valid_donor_list
在Recipient上设置Donor白名单,Recipient只能克隆白名单中指定的实例。在执行克隆操作之前,必须设置该参数。
11)clone_ssl_ca,clone_ssl_cert,clone_ssl_key
SSL相关。
>>>>
参考资料
作者丨陈臣
来源丨公众号:MySQL实战(ID:MySQLInAction)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
关于我们
dbaplus社群是围绕Database、BigData、AIOps的企业级专业社群。资深大咖、技术干货,每天精品原创文章推送,每周线上技术分享,每月线下技术沙龙,每季度Gdevops&DAMS行业大会。
关注公众号【dbaplus社群】,获取更多原创技术文章和精选工具下载
留言与评论(共有 0 条评论) “” |