技术分享 | 实战 MySQL 8.0.17 Clone Plugin

原创: 陈俊聪

背景

很神奇,5.7.17 和 8.0.17,连续两个17小版本都让人眼前一亮。前者加入了组复制(Group Replication)功能,后者加入了克隆插件(Clone Plugin)功能。今天我们实战测试一下这个新功能。

 

克隆插件简介

克隆插件允许在本地或从远程 MySQL 实例克隆数据。克隆数据是存储在 InnoDB 其中的数据的物理快照,其中包括库、表、表空间和数据字典元数据。克隆的数据包含一个功能齐全的数据目录,允许使用克隆插件进行 MySQL 服务器配置。

 

克隆插件支持两种克隆方式

  • 本地克隆

  • 远程克隆

 

本地克隆

本地克隆操作将启动克隆操作的 MySQL 服务器实例中的数据克隆到同服务器或同节点上的一个目录里

远程克隆

默认情况下,远程克隆操作会删除接受者(recipient)数据目录中的数据,并将其替换为捐赠者(donor)的克隆数据。(可选)您也可以将数据克隆到接受者的其他目录,以避免删除现有数据。

远程克隆操作和本地克隆操作克隆的数据没有区别,数据是相同的。

克隆插件支持复制。除克隆数据外,克隆操作还从捐赠者中提取并传输复制位置信息,并将其应用于接受者,从而可以使用克隆插件来配置组复制或主从复制。使用克隆插件进行配置比复制大量事务要快得多,效率更高。

 

实战部分

一、本地克隆

安装克隆插件

启动前

[mysqld]
plugin-load-add=mysql_clone.so

或运行中

INSTALL PLUGIN clone SONAME 'mysql_clone.so';

| 第二种方法会注册到元数据,所以不用担心重启插件会失效。两种方法都很好用

检查插件有没有启用

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone | ACTIVE |
+-------------+---------------+
1 row in set (0.01 sec)

设置强制启动失败参数

[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT

 

如果克隆插件对你们很重要,可以设置clone=FORCE_PLUS_PERMANENT或clone=FORCE。作用是:如果插件未成功初始化,就会强制mysqld启动失败。

克隆需要的权限

需要有备份锁的权限。备份锁是 MySQL 8.0 的新特性之一,比5.7版本的flush table with read lock要轻量。

mysql> CREATE USER clone_user@'%' IDENTIFIED by 'password';
mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user'; # BACKUP_ADMIN是MySQL8.0 才有的备份锁的权限

执行本地克隆

mysql -uclone_user -ppassword -S /tmp/mysql3008.sock
mysql> CLONE LOCAL DATA DIRECTORY = '/fander/clone_dir';

例子中需要 MySQL 的运行用户拥有 fander 目录的rwx权限,要求 clone_dir 目录不存在

本地克隆的步骤如下

  • DROP DATA

  • FILE COPY

  • PAGE COPY

  • REDO COPY

  • FILE SYNC

观察方法如下

mysql> SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress;
+-----------+-------------+----------------------------+
| STAGE | STATE | END_TIME |
+-----------+-------------+----------------------------+
| DROP DATA | Completed | 2019-07-25 21:00:18.858471 |
| FILE COPY | Completed | 2019-07-25 21:00:19.071174 |
| PAGE COPY | Completed | 2019-07-25 21:00:19.075325 |
| REDO COPY | Completed | 2019-07-25 21:00:19.076661 |
| FILE SYNC | Completed | 2019-07-25 21:00:19.168961 |
| RESTART | Not Started | NULL |
| RECOVERY | Not Started | NULL |
+-----------+-------------+----------------------------+
7 rows in set (0.00 sec)

当然还有另外一个观察方法

mysql> set global log_error_verbosity=3;
Query OK, 0 rows affected (0.00 sec)

mysql> CLONE LOCAL DATA DIRECTORY = '/fander/clone6_dir';
Query OK, 0 rows affected (0.24 sec)

[root@192-168-199-101 data]# tailf mysql-error.err
2019-07-25T22:22:58.261861+08:00 8 [Note] [MY-013457] [InnoDB] Clone Begin Master Task by root@localhost
2019-07-25T22:22:58.262422+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply Master Loop Back
2019-07-25T22:22:58.262523+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply Begin Master Task
...
2019-07-25T22:22:58.471108+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State FLUSH DATA:
2019-07-25T22:22:58.472178+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State FLUSH REDO:
2019-07-25T22:22:58.506488+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State DONE
2019-07-25T22:22:58.506676+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply End Master Task ID: 0 Passed, code: 0:
2019-07-25T22:22:58.506707+08:00 8 [Note] [MY-013457] [InnoDB] Clone End Master Task ID: 0 Passed, code: 0:

测试,起一个克隆的实例

/opt/mysql8.0/bin/mysqld --datadir=/fander/clone_dir --port=3333 --socket=/tmp/mysql3333.sock --user=mysql3008user --lower-case-table-names=1 --mysqlx=OFF

#解释,因为我没有使用my.cnf,所以加了比较多参数
#--datadir 指定启动的数据目录
#--port 指定启动的MySQL监听端口
#--socket 指定socket路径
#--user `捐赠者`的目录权限是mysql3008user:mysql3008user,用户也是mysql3008user,我没有修改
#--lower-case-table-names=1 同`捐赠者`
#--mysqlx=OFF 不关闭的话,默认mysqlx端口会合`捐赠者`的33060重复冲突

#登录检查
mysql -uroot -proot -S /tmp/mysql3333.sock
mysql> show master status\G # 可见GTID是`捐赠者`的子集,所以说明`接受者`直接和`捐赠者`建主从复制是很简单的

 

二、远程克隆

远程克隆的前提条件和限制

  • 捐赠者和接受者都需要安装克隆插件

  • 捐赠者和接受者分别需要有至少BACKUP_ADMIN/CLONE_ADMIN权限的账号

    | 暗示了接受者必须先启动一个数据库实例(空或有数据的实例均可,因为都会被删除)

  • 克隆目标目录必须有写入权限

  • 克隆操作期间不允许使用 DDL,允许并发DML。要求相同版本号,您无法MySQL 5.7和MySQL 8.0之间进行克隆,而且要求版本>=8.0.17

  • 同一平台同一架构,例如linux to windows、x64 to x32 是不支持。

  • 足够的磁盘空间

  • 可以克隆操作一般表空间,但必须要有目录权限,不支持克隆使用绝对路径创建的一般空间。与源表空间文件具有相同路径的克隆表空间文件将导致冲突

  • 远程克隆时不支持CLONE INSTANCE FROM中通过使用mysqlx的端口

  • 克隆插件不支持克隆MySQL服务器配置my.cnf等

  • 克隆插件不支持克隆二进制日志。

  • 克隆插件仅克隆存储的数据 InnoDB。不克隆其他存储引擎数据。MyISAM并且 CSV存储在包括sys模式的任何模式中的表都被克隆为空表。

  • 不支持通过MySQL router连接到捐赠者实例。

  • 一些参数是必须一致的,例如innodb_page_size、innodb_data_file_path、--lower_case_table_    names

  • 如果克隆加密或页面压缩数据,则捐赠者和接收者必须具有相同的文件系统块大小

  • 如果要克隆加密数据,则需要安全连接

  • clone_valid_donor_list 在接受者的设置必须包含捐赠者 MySQL 服务器实例的主机地址。

  • 必须没有其他克隆操作正在运行。一次只允许一次克隆操作。要确定克隆操作是否正在运行,请查询该 clone_status表。

  • 默认情况下,克隆数据后会自动重新启动接受者 MySQL 实例。要自动重新启动,必须在接收方上提供监视进程以检测服务器是否已关闭。否则,在克隆数据后,克隆操作将停止并出现以下错误,并且关闭接受者 MySQL 服务器实例:

 

| 此错误不表示克隆失败。这意味着必须在克隆数据后手动重新启动接受者的 MySQL 实例。

远程克隆实战

假设前提条件都满足,步骤如下

和本地克隆一样,远程克隆需要插件安装和用户授权。捐赠者、接受者的授权略有不同。

1. 确保捐赠者和接受者都安装了克隆插件

INSTALL PLUGIN clone SONAME 'mysql_clone.so';

2. 用户账号授权

捐赠者授权

mysql> CREATE USER clone_user@'192.168.199.101' IDENTIFIED by 'password1';
mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user'@'192.168.199.101'; # BACKUP_ADMIN是MySQL8.0 才有的备份锁的权限

接受者授权

mysql> CREATE USER clone_user@'192.168.199.102' IDENTIFIED by 'password2';
mysql> GRANT CLONE_ADMIN ON *.* TO 'clone_user'@'192.168.199.102';

 

| CLONE_ADMIN权限 = BACKUP_ADMIN权限 + SHUTDOWN权限。SHUTDOWN仅限允许用户shutdown和restart mysqld。授权不同是因为,接受者需要restart mysqld。

3. 接受者设置捐赠者列表清单

mysql -uclone_user -ppassword2 -h192.168.199.102 -P3008
mysql> SET GLOBAL clone_valid_donor_list = '192.168.199.101:3008';

 

这看起来是一个安全相关参数。多个实例用逗号分隔,例如“HOST1:PORT1,HOST2:PORT2,HOST3:PORT3”

接受者开始拉取克隆捐赠者数据​​​​​​​

CLONE INSTANCE FROM clone_user@'192.168.199.101':3008
IDENTIFIED BY 'password1';

远程克隆步骤如下

mysql> SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress;
+-----------+-----------+----------------------------+
| STAGE | STATE | END_TIME |
+-----------+-----------+----------------------------+
| DROP DATA | Completed | 2019-07-25 21:56:01.725783 |
| FILE COPY | Completed | 2019-07-25 21:56:02.228686 |
| PAGE COPY | Completed | 2019-07-25 21:56:02.331409 |
| REDO COPY | Completed | 2019-07-25 21:56:02.432468 |
| FILE SYNC | Completed | 2019-07-25 21:56:02.576936 |
| RESTART | Completed | 2019-07-25 21:56:06.564090 |
| RECOVERY | Completed | 2019-07-25 21:56:06.892049 |
+-----------+-----------+----------------------------+
7 rows in set (0.01 sec)

接受者如果非mysqld_safe启动的,会报错误,但不影响克隆,需要您人手启动mysqld即可。

ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process).

实操后小结:克隆与xtrabackup的对比

  • 克隆和xtrabackup备份都属于物理热备,备份恢复原理也近似。

  • 克隆在恢复实例时需要先启动一个实例并授权,而xtrabackup不需要。

  • xtrabackup在backup后需要apply log,克隆是类似mysqlbackup提供的backup-and-apply-log,合并在一起做。

  • xtrabackup备份文件的权限等于执行命令的人的权限,恢复实例时需要人手chown回实例权限,克隆备份后权限和原数据权限一致,无需再人手chown,方便恢复。

  • xtrabackup恢复时需要在mysql中执行reset master;然后set global gtid_purged="UUID:NUMBER",具体的UUID:NUMBER的值为备份文件中的xtrabackup_info文件的内容;克隆不需要这个操作步骤,默认克隆完就可以建立复制了。

  • xtrabackup备份完一般是scp拷贝到另外一台机器恢复,走的是22端口;克隆走的是MySQL的监听端口。所以在目录权限正确的情况下,甚至根本不需要登录Linux服务器的权限。如下:

[root@192-168-199-103 ~]# mysql -uroot -ppassword2 -h192.168.199.102 -P3008 -e "SET GLOBAL clone_valid_donor_list = '192.168.199.101:3008';"

mysql: [Warning] Using a password on the command line interface can be insecure.
[root@192-168-199-103 ~]# mysql -uroot -ppassword2 -h192.168.199.102 -P3008 -e "CLONE INSTANCE FROM root@'192.168.199.101':3008 IDENTIFIED BY 'password1';"
mysql: [Warning] Using a password on the command line interface can be insecure.

三、利用克隆建立主从复制

克隆出来的接受者实例,可以与捐赠者建立主从复制。当然建立组复制也是可以的,鉴于篇幅的原因,不做示例有兴趣可以阅读官方文档18.4.3.1节“克隆分布式恢复”。

| https://dev.mysql.com/doc/refman/8.0/en/group-replication-cloning.html

传统复制时,通过以下命令查看postion位置

mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
+------------------+-----------------+
| BINLOG_FILE | BINLOG_POSITION |
+------------------+-----------------+
| mysql-bin.000014 | 2179 |
+------------------+-----------------+
1 row in set (0.01 sec)

GTID复制时,通过以下命令查看GTID位置​​​​​​​

mysql> SELECT @@GLOBAL.GTID_EXECUTED;
+-------------------------------------------+
| @@GLOBAL.GTID_EXECUTED |
+-------------------------------------------+
| 990fa9a4-7aca-11e9-89fa-000c29abbade:1-11 |
+-------------------------------------------+
1 row in set (0.00 sec)

假设已经有如下授权,我们就可以建立复制啦

create user repl@'%' identified WITH 'mysql_native_password' by 'password';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'%';

建立GTID主从复制关系

(接受者上)

  1. CHANGE MASTER TO
    MASTER_HOST='192.168.199.101',
    MASTER_USER='repl',
    MASTER_PASSWORD='password',
    MASTER_PORT=3008,
    MASTER_AUTO_POSITION=1;
    
    

     

监控克隆操作

检查克隆进度

mysql> SELECT STATE FROM performance_schema.clone_status;
+-----------+
| STATE |
+-----------+
| Completed |
+-----------+
1 row in set (0.00 sec)

 

SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;

检查克隆是否出错

mysql> SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;
+-----------+----------+---------------+
| STATE | ERROR_NO | ERROR_MESSAGE |
+-----------+----------+---------------+
| Completed | 0 | |
+-----------+----------+---------------+
1 row in set (0.00 sec)

检查克隆次数

show global status like 'Com_clone'; # `捐赠者` 每次+1,`接受者` 0

随时可以kill掉克隆

使用
SELECT * FROM performance_schema.clone_status\G
或
show processlist
查看线程ID,然后kill ID

总结

克隆功能非常有趣。他操作简单,可以用于快速搭建、恢复主从复制或组复制,可以部分取代开源热备软件xtrabackup,期待未来官方会把他做得越来越好,功能越来越丰富。

转载于:https://my.oschina.net/actiontechoss/blog/3080414

### 配置 MySQL 主从复制 MySQL 主从复制是一种常见的数据库高可用性和负载均衡方案,通过将主服务器(Master)的数据复制到一个或多个从服务器(Slave),可以实现数据的冗余备份、读写分离和故障转移。以下是实现 MySQL 主从复制的详细步骤。 #### 1. 准备工作 在开始配置之前,需要确保以下几点: - 主服务器和从服务器都已安装 MySQL,并且版本兼容。 - 确保主服务器和从服务器之间的网络连接畅通。 - 主服务器和从服务器的 `server-id` 必须不同,且从服务器的 `server-id` 不能与主服务器相同。 #### 2. 配置主服务器(Master) 首先,在主服务器上启用二进制日志(Binary Log),并设置唯一的 `server-id`。编辑 MySQL 的配置文件(通常是 `/etc/my.cnf` 或 `/etc/mysql/my.cnf`),添加或修改以下内容: ```ini [mysqld] server-id=1 log-bin=mysql-bin ``` 保存并重启 MySQL 服务以使配置生效。 接下来,创建一个专门用于主从复制的用户,并授予相应的权限: ```sql CREATE USER 'replica'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES; ``` 然后,查看主服务器当前的二进制日志文件名和位置,以便在从服务器上指定同步点: ```sql SHOW MASTER STATUS; ``` 输出示例: | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | |-------------------|----------|--------------|------------------| | mysql-bin.000001 | 1000 | | | 记录下 `File` 和 `Position` 的值,后续配置从服务器时会用到。 #### 3. 配置从服务器(Slave) 在从服务器上同样需要设置唯一的 `server-id`,并且要小于主服务器的 `server-id`。编辑 MySQL 的配置文件,添加或修改以下内容: ```ini [mysqld] server-id=2 ``` 保存并重启 MySQL 服务。 接下来,停止从服务器的复制进程(如果之前已经配置过),并重置所有复制相关的设置: ```sql STOP SLAVE; RESET SLAVE ALL; ``` 然后,使用 `CHANGE MASTER TO` 命令指定主服务器的信息,包括 IP 地址、复制用户、密码、二进制日志文件名和位置: ```sql CHANGE MASTER TO MASTER_HOST='10.1.1.90', MASTER_USER='replica', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1000; ``` 最后,启动从服务器的复制进程: ```sql START SLAVE; ``` #### 4. 验证主从复制是否正常运行 在从服务器上执行以下命令,查看复制状态: ```sql SHOW SLAVE STATUS\G ``` 重点关注以下两个字段: - `Slave_IO_Running`: YES - `Slave_SQL_Running`: YES 如果这两个字段的值都是 `YES`,则表示主从复制已经成功启动。 #### 5. 常见问题及解决方法 - **网络问题**:确保主服务器和从服务器之间的网络连接正常,可以通过 `ping` 或 `telnet` 测试端口连通性。 - **权限问题**:确保复制用户具有 `REPLICATION SLAVE` 权限,并且可以从从服务器访问主服务器。 - **日志文件或位置错误**:如果 `CHANGE MASTER TO` 中指定的 `MASTER_LOG_FILE` 或 `MASTER_LOG_POS` 不正确,会导致复制失败。可以通过 `SHOW MASTER STATUS` 在主服务器上重新获取正确的日志文件和位置。 - **UUID 冲突**:如果从服务器的 `server-id` 与主服务器相同,或者从服务器的 UUID 与其他从服务器冲突,也会导致复制失败。确保每个服务器的 `server-id` 唯一。 #### 6. 克隆数据库 除了配置主从复制外,还可以通过克隆数据库的方式快速创建一个与主服务器相同的数据副本。MySQL 提供了多种方式来克隆数据库,以下是两种常见的方法: ##### 方法一:使用 `mysqldump` 工具 `mysqldump` 是 MySQL 自带的一个命令行工具,可以用来导出数据库的结构和数据。在主服务器上执行以下命令,将数据库导出为 SQL 文件: ```bash mysqldump -u root -p --single-transaction --master-data=2 database_name > backup.sql ``` 其中,`--single-transaction` 选项确保导出的数据是一致的快照,而 `--master-data=2` 选项会在导出的 SQL 文件中插入 `CHANGE MASTER TO` 语句,记录当前的二进制日志文件和位置。 将 `backup.sql` 文件传输到从服务器,并导入数据库: ```bash mysql -u root -p database_name < backup.sql ``` 导入完成后,根据 `backup.sql` 文件中的 `CHANGE MASTER TO` 语句,配置从服务器的复制设置。 ##### 方法二:使用 MySQL 的克隆插件(MySQL 8.0+) 从 MySQL 8.0 开始,MySQL 引入了克隆插件(Clone Plugin),允许直接克隆整个数据库实例。克隆插件可以在不中断主服务器的情况下,将主服务器的数据、日志、表空间等完整地复制到从服务器。 在从服务器上安装克隆插件: ```sql INSTALL PLUGIN clone SONAME 'mysql_clone.so'; ``` 然后,使用 `CLONE INSTANCE` 命令克隆主服务器的数据: ```sql CLONE INSTANCE FROM 'replica'@'10.1.1.90':3306 IDENTIFIED BY 'password'; ``` 克隆完成后,从服务器会自动停止,并重新启动以应用克隆的数据。克隆插件的优势在于它能够高效地复制大量数据,并且不会影响主服务器的性能。 #### 7. 主从复制的应用场景 - **读写分离**:通过主从复制,可以将写操作集中在主服务器上,而将读操作分散到多个从服务器上,从而提高系统的并发处理能力。 - **数据备份与恢复**:从服务器可以作为主服务器的备份,当主服务器发生故障时,可以快速切换到从服务器,确保业务连续性。 - **负载均衡**:通过多个从服务器分担读请求,可以有效降低主服务器的压力,提升整体系统的性能。 - **数据分析**:可以将从服务器用于数据分析、报表生成等操作,避免对主服务器造成额外负担。 #### 8. 主从复制的注意事项 - **延迟问题**:由于主从复制是异步的,从服务器可能会存在一定的数据延迟。如果对数据一致性要求较高,可以考虑使用半同步复制(Semi-Synchronous Replication)或组复制(Group Replication)。 - **数据一致性**:在主从复制过程中,如果主服务器发生了某些操作(如 `DELETE`、`UPDATE`),而从服务器未能及时同步,可能会导致数据不一致。可以通过定期检查 `SHOW SLAVE STATUS` 来监控复制状态。 - **版本兼容性**:不同版本的 MySQL 可能会对复制行为产生影响,建议主从服务器使用相同的 MySQL 版本,以避免兼容性问题。 - **安全性**:为了防止未经授权的访问,建议对复制用户进行严格的权限控制,并使用 SSL 加密连接,确保数据传输的安全性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值