mysql视频教程栏目介绍mysql 8的新特性clone plugin
clone plugin是mysql 8.0.17引入的一个重大特性,为什么要实现这个特性呢?个人感觉,主要还是为group replication服务。在group replication中,添加一个新的节点,差异数据的补齐是通过分布式恢复(distributed recovery)来实现的。
在mysql 8.0.17之前,只支持一种恢复方式-binlog。但如果新节点需要的binlog已经被purge了,这个时候,只能先借助于备份工具(xtrabackup,mydumper,mysqldump)做个全量数据的同步,然后再通过分布式恢复同步增量数据。
这种方式,虽然也能实现添加节点的目的,但总归还是要借助于外部工具,需要一定的工作量和使用门槛。要知道,其竞争对手,pxc,默认集成了xtrabackup进行state snapshot transfer(类似于全量同步),而mongodb则更进一步,原生就实现了initial sync同步全量数据。从易用性来看,单就集群添加节点这一项而言,mysql确实不如其竞争对手。客户体验上,还有很大的提升空间。
好在mysql官方也正视到这个差距,终于在mysql 8.0.17实现了clone plugin。当然,对于官方来说,实现这个特性并不算难,毕竟有现成的物理备份工具(mysql enterprise backup)可供借鉴。
本文将从以下几个方面展开:
clone plugin的安装clone plugin的使用如何查看克隆操作的进度如何基于克隆数据搭建从库clone plugin的实现细节clone plugin的限制clone plugin与xtrabackup的对比clone plugin的参数解析一、clone plugin的安装clone plugin支持以下两种安装方式:
(1)配置文件指定
[mysqld]plugin-load-add=mysql_clone.soclone=force_plus_permanent复制代码
这里的clone,严格来说,不是参数名,而是插件名,可加可不加,force_plus_permanent 控制插件的行为。
有四个取值:
on**(**开启插件)off(禁用插件)force(强制开启。如果插件初始化失败,mysql将不会启动)force_plus_permanent(在force的基础上,不允许通过uninstall plugin命令卸载插件)。(2)动态加载
[mysqld]plugin-load-add=mysql_clone.soclone=force_plus_permanent复制代码
查看插件是否安装成功
mysql> show plugins;...| clone | active | clone | mysql_clone.so | gpl |...复制代码
clone状态显示为”active“代表插件加载成功。
二、clone plugin的使用clone plugin支持两种克隆方式:本地克隆和远程克隆。
1、 本地克隆
本地克隆是在实例本地发起的,其语法如下:
clone local data directory [=] 'clone_dir';复制代码
其中,clone_dir是克隆目录。
下面看个具体的demo。
创建克隆用户
mysql> create user 'clone_user'@'%' identified by 'clone_pass';mysql> grant backup_admin on *.* to 'clone_user'@'%';复制代码
创建克隆目录
# mkdir /data/mysql# chown -r mysql.mysql /data/mysql复制代码
创建本地克隆
# mysql -uclone_user -pclone_passmysql> clone local data directory='/data/mysql/3307';复制代码
其中,“/data/mysql/3307” 是克隆目录,其需满足以下几点要求:
克隆目录必须是绝对路径。“/data/mysql”必须存在,且mysql对其有可写权限。3307不能存在。查看克隆目录的内容
# ll /data/mysql/3307total 172996drwxr-x--- 2 mysql mysql 89 may 24 22:37 #clone-rw-r----- 1 mysql mysql 3646 may 24 22:37 ib_buffer_pool-rw-r----- 1 mysql mysql 12582912 may 24 22:37 ibdata1-rw-r----- 1 mysql mysql 50331648 may 24 22:37 ib_logfile0-rw-r----- 1 mysql mysql 50331648 may 24 22:37 ib_logfile1drwxr-x--- 2 mysql mysql 6 may 24 22:37 mysql-rw-r----- 1 mysql mysql 25165824 may 24 22:37 mysql.ibddrwxr-x--- 2 mysql mysql 20 may 24 22:37 slowtechdrwxr-x--- 2 mysql mysql 28 may 24 22:37 sys-rw-r----- 1 mysql mysql 10485760 may 24 22:37 undo_001-rw-r----- 1 mysql mysql 11534336 may 24 22:37 undo_002复制代码
相对于xtrabackup,无需prepare,直接即可启动使用。
# /usr/local/mysql/bin/mysqld --no-defaults --datadir=/data/mysql/3307 --user mysql --port 3307 &复制代码
2、远程克隆
远程克隆涉及两个实例,其中,待克隆的实例是donor,接受克隆数据的实例是recipient。克隆命令需在recipient上发起,语法如下:
clone instance from 'user'@'host':portidentified by 'password'[data directory [=] 'clone_dir'][require [no] ssl];复制代码
其中,host,port 是待克隆实例的(donor)的ip和端口,user,password是donor上的克隆用户和密码,需要backup_admin权限,如上面创建的clone_user。
data directory指定备份目录,不指定的话,则默认克隆到recipient的数据目录下。
require [no] ssl,是否开启ssl通信。
下面,看个具体demo。
首先,在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';复制代码
backup_admin是克隆操作必需权限。
接着,在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(阻塞ddl)和shutdown(重启实例)权限。
设置donor白名单。recipient只能克隆白名单中的实例。
mysql> set global clone_valid_donor_list = '192.168.244.10:3306';复制代码
设置该参数需要system_variables_admin权限。
在recipient上发起克隆命令
# mysql -urecipient_user -precipient_passmysql> clone instance from 'donor_user'@'192.168.244.10':3306 identified by 'donor_pass';query ok, 0 rows affected (36.97 sec)复制代码
远程克隆会依次进行以下操作:
**(1)****获取备份锁。**备份锁和ddl互斥。注意,不仅仅是recipient,donor上的备份锁同样会获取。
**(2)****drop用户表空间。**注意,drop的只是用户数据,不是数据目录,也不包括mysql,ibdata等系统表空间。
**(3)从donor实例拷贝数据。**对于用户表空间,会直接拷贝,如果是系统表空间 ,则会重命名为xxx.#clone,不会直接替代原文件。
ll /data/mysql/3306/data/...-rw-r----- 1 mysql mysql 3646 may 25 07:20 ib_buffer_pool-rw-r----- 1 mysql mysql 3646 may 27 07:31 ib_buffer_pool.#clone-rw-r----- 1 mysql mysql 12582912 may 27 07:31 ibdata1-rw-r----- 1 mysql mysql 12582912 may 27 07:31 ibdata1.#clone-rw-r----- 1 mysql mysql 50331648 may 27 07:32 ib_logfile0-rw-r----- 1 mysql mysql 50331648 may 27 07:31 ib_logfile0.#clone...-rw-r----- 1 mysql mysql 25165824 may 27 07:31 mysql.ibd-rw-r----- 1 mysql mysql 25165824 may 27 07:31 mysql.ibd.#clone...复制代码
**(4)重启实例。**在启动的过程中,会用xxx.#clone替换掉原来的系统表空间文件。
三、如何查看克隆操作的进度查看克隆操作的进度主要依托于performance_schema.clone_status和performance_schema.clone_progress这两张表。
首先看看performance_schema.clone_status表。
mysql> select * from performance_schema.clone_status\g*************************** 1\. row *************************** id: 1 pid: 0 state: completed begin_time: 2020-05-27 07:31:24.220 end_time: 2020-05-27 07:33:08.185 source: 192.168.244.10:3306 destination: local instance error_no: 0 error_message: binlog_file: mysql-bin.000009binlog_position: 665197555 gtid_executed: 59cd4f8f-8fa1-11ea-a0fe-000c29f66609:1-5601 row in set (0.06 sec)复制代码
顾名思义,该表记录了克隆操作的当前状态。
其中,
**pid:**processlist id。对应show processlist中的id,如果要终止当前的克隆操作,执行kill processlist_id命令即可。
**state:**克隆操作的状态,not started(克隆尚未开始),in progress(克隆中),completed(克隆成功),failed(克隆失败)。如果是failed状态,error_no,error_message会给出具体的错误编码和错误信息。
**begin_time,end_time:**克隆操作开始,结束时间。
**source:**donor实例的地址。
**destination:**克隆目录。“local instance”代表当前实例的数据目录。
**gtid_executed,binlog_file(binlog_position):**克隆操作结束时,主库已经执行的gtid集合,及一致性位置点。可利用这些信息来搭建从库。
接下来看看performance_schema.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 | 2020-05-27 07:31:28.581661 | 2020-05-27 07:31:35.855706 | 1 | 0 | 0 | 0 | 0 | 0 || 1 | file copy | completed | 2020-05-27 07:31:35.855952 | 2020-05-27 07:31:58.270881 | 2 | 482463294 | 482463294 | 482497011 | 0 | 0 || 1 | page copy | completed | 2020-05-27 07:31:58.271250 | 2020-05-27 07:31:58.719085 | 2 | 10977280 | 10977280 | 11014997 | 0 | 0 || 1 | redo copy | completed | 2020-05-27 07:31:58.720128 | 2020-05-27 07:31:58.930804 | 2 | 465408 | 465408 | 465903 | 0 | 0 || 1 | file sync | completed | 2020-05-27 07:31:58.931094 | 2020-05-27 07:32:01.063325 | 2 | 0 | 0 | 0 | 0 | 0 || 1 | restart | completed | 2020-05-27 07:32:01.063325 | 2020-05-27 07:32:59.844119 | 0 | 0 | 0 | 0 | 0 | 0 || 1 | recovery | completed | 2020-05-27 07:32:59.844119 | 2020-05-27 07:33:08.185367 | 0 | 0 | 0 | 0 | 0 | 0 |+------+-----------+-----------+----------------------------+----------------------------+---------+-----------+-----------+-----------+------------+---------------+7 rows in set (0.00 sec)复制代码
该表记录了克隆操作的进度信息。
**stage:**一个克隆操作可依次细分为drop data,file copy,page copy,redo copy,file sync,restart,recovery等7个阶段。当前阶段结束了才会开始下一个阶段。
**state:**当前阶段的状态。有三种状态:not started,in progress,completed。
**begin_time,end_time:**当前阶段的开始时间和结束时间。
**threads:**当前阶段使用的并发线程数。
**estimate:**预估的数据量。
**data:**已经拷贝的数据量。
**network:**通过网络传输的数据量。如果是本地克隆,该列的值为0。
**data_speed,network_speed:**当前数据拷贝的速率和网络传输的速率。
注意,是当前值。
四、如何基于克隆数据搭建从库在前面,我们介绍过performance_schema.clone_status表,该表会记录donor实例的一致性位置点信息。我们可以利用这些信息来搭建从库。
mysql> select * from performance_schema.clone_status\g*************************** 1\. row ***************************... binlog_file: mysql-bin.000009binlog_position: 665197555 gtid_executed: 59cd4f8f-8fa1-11ea-a0fe-000c29f66609:1-5601 row in set (0.06 sec)复制代码
这里,区分两种场景,gtid复制和基于位置点的复制。
1、gtid复制mysql> change master to master_host = 'master_host_name', master_port = master_port_num, ... master_auto_position = 1;mysql> start slave;复制代码
需要注意的是,无需额外执行set global gtid_purged操作。通过克隆数据启动的实例,gtid_purged已经初始化完毕。
mysql> show global variables like 'gtid_purged';+---------------+--------------------------------------------+| variable_name | value |+---------------+--------------------------------------------+| gtid_purged | 59cd4f8f-8fa1-11ea-a0fe-000c29f66609:1-560 |+---------------+--------------------------------------------+1 row in set (0.00 sec)复制代码
2、基于位置点的复制这里,同样要区分两种场景。
场景1,recipient要作为donor的从库。
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。
场景2,donor本身就是一个从库,recipient要作为donor主库的从库。
mysql> select master_log_name, master_log_pos from mysql.slave_relay_log_info;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:mysql.slave_relay_log_info中的master_log_name,master_log_pos(分别对应 show slave status 中的 relay_master_log_file,exec_master_log_pos)。
在搭建从库时,建议设置--skip-slave-start。该参数默认为off,实例启动后,会自动执行start slave操作。
如果donor是个从库,recipient会基于mysql.slave_master_info,mysql.slave_relay_log_info中的信息自动建立复制,很多时候,这未必是我们的预期行为。
五、clone plugin的实现细节克隆操作可细分为以下5个阶段。
[init] ---> [file copy] ---> [page copy] ---> [redo copy] -> [done]复制代码
**1、init:**初始化一个克隆对象。
**2、file copy:**拷贝所有数据文件。在拷贝之前,会记录一个lsn,作为“clone start lsn”,这个lsn其实是当前checkpoint的lsn,同时启动“page tracking”特性。
“page tracking”会跟踪“clone start lsn”之后被修改的页,具体来说,会记录该页的tablespace id和page id。数据文件拷贝结束后,会将当前checkpoint的lsn记为“clone file end lsn”。
**3、page copy:**拷贝“clone start lsn”和“clone file end lsn”之间的页,在拷贝之前,会对这些页进行排序-基于tablespace id和page id,尽量避免拷贝过程中出现随机读写。同时,开启“redo archiving”特性。
“redo archiving”会在后台开启一个归档线程将redo文件中的内容按chunk拷贝到归档文件中。通常来说,归档线程的拷贝速度会快于redo日志的生成速度。即使慢于,在写入新的redo日志时,也会等待归档线程完成拷贝,不会出现还未拷贝的redo日志被覆盖的情况。当所有修改的页拷贝完毕后,会获取实例的一致性位置点信息,此时的lsn记为“clone lsn”。
4、redo copy:拷贝归档文件中“clone file end lsn”与“clone lsn”之间的redo日志。
**5、done:**调用snapshot_end()销毁克隆对象。
六、clone plugin的限制1、克隆期间,不允许执行ddl命令。同样,ddl会阻塞克隆命令的执行
2、clone plugin不会拷贝donor的配置参数。
3、clone plugin不会拷贝donor的二进制日志文件。
4、clone plugin只会拷贝innodb表的数据,对于其它存储引擎的表,只会拷贝表结构。
5、donor实例中如果有表通过data directory指定了绝对路径,在进行本地克隆时,会提示文件已存在。在进行远程克隆时,绝对路径必须存在且有可写权限。
6、不允许通过mysql router连接donor实例。
7、执行clone instance操作时,指定的donor端口不能为x protocol端口。
除此之外,在进行远程克隆时,还会进行如下检查:
mysql版本(包括小版本)必须一致,且支持clone plugin。error 3864 (hy000): clone donor mysql version: 8.0.20 is different from recipient mysql version 8.0.19.复制代码
主机的操作系统和位数(32位,64位)必须一致。两者可根据version_compile_os,version_compile_machine参数获取。recipient必须有足够的磁盘空间存储克隆数据。字符集(character_set_server),校验集(collation_server),character_set_filesystem必须一致。innodb_page_size必须一致。会检查innodb_data_file_path中ibdata的数量和大小。目前clone plugin(8.0.20)的实现,无论是donor,还是recipient,同一时间,只能执行一个克隆操作。后续会支持多个克隆操作并发执行。error 3634 (hy000): too many concurrent clone operations. maximum allowed - 1.复制代码
recipient需要重启,所以其必须通过mysqld_safe或systemd等进行管理。如果是通过mysqld进行启动,实例关闭后,需要手动启动。error 3707 (hy000): restart server failed (mysqld is not managed by supervisor process).复制代码
active状态的plugin必须一致。七、clone plugin与xtrabackup的对比1、在实现上,两者都有file copy和redo copy阶段,但clone plugin比xtrabackup多了一个page copy,由此带来的好处是,clone plugin的恢复速度比xtrabackup更快。
2、xtrabackup没有redo archiving特性,有可能出现未拷贝的redo日志被覆盖的情况。
3、gtid下建立复制,无需额外执行set global gtid_purged操作。
八、clone plugin的参数解析clone_autotune_concurrency 是否自动调节克隆过程中并发线程数的数量,默认为on,此时,最大线程数受clone_max_concurrency参数控制。若设置为off,则并发线程数的数量将是固定的,同clone_max_concurrency参数一致。该参数的默认值为16。clone_buffer_size 本地克隆时,中转缓冲区的大小,默认4m。缓冲区越大,备份速度越快,相应的,对磁盘io的压力越大。clone_ddl_timeout 克隆操作需要获取备份锁(backup lock)。如果在执行clone命令时,有ddl在执行,则clone命令会被阻塞,等待获取备份锁(waiting for backup lock)。等待的最大时长由clone_ddl_timeout参数决定,默认300(单位秒)。如果在这个时间内还没获取到锁,clone命令会失败,且提示“error 1205 (hy000): lock wait timeout exceeded; try restarting transaction”。需要注意的是,如果在执行ddl时,有clone命令在执行,ddl同样会因获取不到备份锁被阻塞,只不过,ddl操作的等待时长由lock_wait_timeout参数决定,该参数的默认值为31536000s,即365天。
clone_enable_compression 远程克隆,在传输数据时,是否开启压缩。开启压缩能节省网络带宽,但相应的,会增加cpu消耗。clone_max_data_bandwidth 远程克隆时,可允许的最大数据拷贝速率(单位mib/s)。默认为0,不限制。注意,这里限制的只是单个线程的拷贝速率,如果存在多个线程并行拷贝,实际最大拷贝速率=clone_max_data_bandwidth*线程数。clone_max_network_bandwidth 远程克隆时,可允许的最大网络传输速率(单位mib/s)。默认为0,不限制。如果网络带宽存在瓶颈,可通过该参数进行限速。clone_valid_donor_list 设置donor白名单,只能克隆白名单中指定的实例。clone_ssl_ca,clone_ssl_cert,clone_ssl_key ssl相关。相关免费学习推荐:mysql视频教程
以上就是看看mysql 8 新特性clone plugin的详细内容。