社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

了解这个MySQL 8.0新特性,添加节点一条命令搞定

DBAplus社群 • 4 年前 • 621 次点击  

作者介绍

陈臣,甲骨文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是克隆目录,它需满足以下几点要求:


  • 克隆目录必须是绝对路径。

  • /data/backup必须存在,且MySQL对其有可写权限。

  • 最后一级目录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];


其中,


  • host,port:被克隆实例(Donor)的 IP 和端口。


  • user,password:Donor 上的克隆用户和密码,需要 backup_admin 权限。


  • DATA DIRECTORY:备份目录。不指定的话,则默认克隆到 Recipient 的数据目录下。


  • REQUIRE [NO] SSL:是否开启 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';

远程克隆会依次执行以下操作:


  • 获取备份锁 (Backup Lock)。备份锁和DDL互斥。注意,获取的不仅仅的是Recipient上的备份锁,Donor上的同样也要获取。


  • Drop用户表空间。注意,Drop的只是用户表空间,不是数据目录,也不包括ib_buffer_pool、ibdata等系统文件。


  • 从Donor实例拷贝数据。对于用户表空间,会直接拷贝。对于系统文件 ,则会重命名为xxx.#clone,不会直接替代原文件。如:


# 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

...


  • 重启实例。在启动的过程中,会用xxx.#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)


其中,


  • PID:Processlist ID。对应show processlist中的Id,如果要终止当前的克隆操作,可执行KILL QUERY processlist_id。


  • STATE:克隆操作的状态,包括:Not Started(克隆尚未开始),In Progress(克隆中),Completed(克隆成功),Failed(克隆失败)。如果是Failed状态,ERROR_MESSAGE会给出具体的报错信息。


  • BEGIN_TIME,END_TIME:克隆操作开始、结束时间。


  • SOURCE:Donor实例的地址。


  • DESTINATION:克隆目录。LOCAL INSTANCE代表当前实例的数据目录。


  • GTID_EXECUTED,BINLOG_FILE(BINLOG_POSITION):克隆操作对应的一致性位置点信息,可利用这些信息搭建从库。


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)


其中,


  • 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:当前数据拷贝速率和网络传输速率。注意,是当前值。


四、如何基于克隆数据搭建从库


需要区分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端口。


除此之外,在进行远程克隆时,还有如下要求:


  • MySQL版本(包括小版本)必须一致。


  • 主机的操作系统和位数(32位,64位)必须一致。两者可基于参数version_compile_os,version_compile_machine获取。


  • Recipient必须有足够的磁盘空间存储克隆数据。


  • 字符集相关参数必须一致,具体包括:character_set_server(字符集),collation_server(校验集)和character_set_filesystem。


  • 参数innodb_page_size必须一致。


  • 无论是Donor,还是Recipient,同一时间,只能执行一个克隆操作。


  • Recipient需要重启,所以其必须通过mysqld_safe或systemd等进程管理工具进行管理,否则实例关闭后需手动拉起。


七、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相关。


>>>>

参考资料


  • InnoDB: Clone local replica

    https://dev.mysql.com/worklog/task/?id=9209

  • InnoDB: Clone remote replica

    https://dev.mysql.com/worklog/task/?id=9210

  • InnoDB: Clone Replication Coordinates

    https://dev.mysql.com/worklog/task/?id=9211

  • InnoDB: Clone Remote provisioning

    https://dev.mysql.com/worklog/task/?id=11636

  • MySQL/InnoDB数据克隆插件(clone plugin)实现剖析

    https://zhuanlan.zhihu.com/p/79328512


作者丨陈臣
来源丨公众号:MySQL实战(ID:MySQLInAction)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/136779