导读
作者张充,知数堂优秀学员,多年DBA经验,擅长MySQL、SQL Server。
什么是Clone Plugin?
MySQL 8.0.17推出的插件,利用克隆插件,可以扩展实现:
SQL命令进行备份。
Slave节点快速搭建。
MGR节点快速扩充。
而克隆插件的基础功能,我的描述是:
可以对本身的实例的InnoDB数据,备份到本服务器的指定目录中。(本地克隆:本地备份)
可以将远程实例的InnoDB数据还原到当前的实例中。(远端克隆:远端备份 + 本实例自动还原)
可以将远程实例的InnoDB数据还原到当前的实例的其他目录中。(远端克隆:远端备份)
一、安装Clone Plugin
1. 每次启动MySQL进程,自动加载插件
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT
2. 在已经运行中的MySQL,手动加载插件
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
执行INSTALL PLUGIN命令后,会注册到mysql.plugins表中,所以下次重启该实例会自动加载插件,无需再依赖plugin-load-add
3. 查看插件状态
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM
INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone | ACTIVE |
+-------------+---------------+
4. 卸载插件
UNINSTALL PLUGIN clone;
5. 导致插件安装失败的原因
如设置:set session explicit_defaults_for_timestamp = 0;
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
ERROR 1123 (HY000): Can't initialize function 'clone';
Plugin initialization function failed.
二、本地克隆 + 还原
本地克隆操作会将数据从启动克隆操作的MySQL服务器实例克隆到运行MySQL服务器实例的同一服务器或节点上的目录中。
1. 注意事项
1.1只克隆innodb存储引擎的数据。非INNODB引擎的表只会生成空表。
1.2 不会克隆原实例的全部目录结构,只克隆了data目录下的相关数据。
1.3 克隆的目标目录必须不存在,克隆过程会生成该目录,所以原实例的启动账户要有创建目录的权限。
1.4 克隆后的目录会自动设置:mysql:mysql
1.5 克隆目标目录不会生成原实例自定义的innodb_undo_directory
1.6 克隆不会拷贝原实例的binlog文件
2. 执行本地克隆(需要登录原实例)
2.1 创建执行克隆命令的MySQL User,权限需要BACKUP_ADMIN
mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user';
2.2 使用具有BACKUP_ADMIN的账号,登录到原实例中,执行:
mysql> clone local data directory = '/data/mysql_3307/data';
Query OK, 0 rows affected (20.40 sec)
2.3 查看克隆的进度
mysql> SELECT STAGE, STATE, END_TIME
FROM performance_schema.clone_progress;
+-----------+-------------+----------------------------+
| STAGE | STATE | END_TIME |
+-----------+-------------+----------------------------+
| DROP DATA | Completed | 2020-04-06 10:45:10.212434 |
| FILE COPY | Completed | 2020-04-06 10:45:20.605570 |
| PAGE COPY | Completed | 2020-04-06 10:45:20.909818 |
| REDO COPY | Completed | 2020-04-06 10:45:21.112235 |
| FILE SYNC | Completed | 2020-04-06 10:45:30.611554 |
| RESTART | Not Started | NULL |
| RECOVERY | Not Started | NULL |
+-----------+-------------+----------------------------+
3. 本地启动克隆实例,以3307端口启动
假设donor中的数据目录结构:
├── data
├── ib_buffer_pool
├── ibdata1
├── ib_logfile0
├── ib_logfile1
├── mybinlog.index
├── mybinlog.000001
├── mybinlog.000002
├── mysql
├── mysql.ibd
├── sys
└── sys_config.ibd
├── undolog
└── undo_001
└── undo_001
├── logs
└── slow.log
└── error.log
├── my.cnf
└── tmp
└── mysql.sock
clone后的目录结构:
├── #clone
│ ├── #replace_files
│ ├── #status_fix
│ ├── #view_progress
│ └── #view_status
├── ib_buffer_pool
├── ibdata1
├── ib_logfile0
├── ib_logfile1
├── mysql
├── mysql.ibd
├── sys
│ └── sys_config.ibd
├── undo_001
└── undo_002
对比donor的原始目录结构和clone后的结构,会发现:
除了data外的目录都没有创建
clone后的目录没有binlog文件
clone后的目录undo目录缺失,但是undo文件放在了clone目录下
所以还原后想采用clone文件启动实例,用原先的my.cnf文件是无法成功的:
/usr/local/mysql8019/bin/mysqld --defaults-file=/data/mysql_3307/my.cnf &
..
[Note] [MY-012905] [InnoDB] Cannot create /data/mysql_3307/data/undolog/undo_001
...because ./undo_001 already uses Space ID=4294967279! Did you change innodb_undo_directory?
[ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Invalid Filename.
[ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine
[ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
# 因为克隆过程,会将自定义的undo目录下的undo文件
# 会与数据文件一起拷贝到一层目录下,并且不会生成原实例的自定义undo目录。
那么我的还原姿势:
1. 将donor的非data目录建立上(原目录:data、logs、tmp):
mkdir /data/mysql_3307/{logs,tmp} -p
# /data/mysql_3307/data目录为clone dir,已存在。
2. 将donnor指定的innodb_undo_directory目录建立,并将undo文件移动到该目录中
mkdir /data/mysql_3307/data/undolog
mv /data/mysql_3307/data/undo_00* /data/mysql_3307/data/undolog/
3. 授权
chown -R mysql:mysql /data/mysql_3307/
4. 再次启动MySQL,成功
/usr/local/mysql8019/bin/mysqld --defaults-file=/data/mysql_3307/my.cnf &
三、 远程克隆数据
从远程的donor上,克隆数据到本地。
1. 注意事项
执行CLONE INSTANCE在非donor实例上执行。
不指定DATA DIRECTORY,将先清空本地数据,再做克隆拷贝,并自动重启MySQL实例(建议mysqld_safe启动)。
若指定DATA DIRECTORY,本地磁盘空间需要更多的空间(克隆数据+本地历史数据),不会自动重启MySQL实例
donor 和 recipient的MySQL版本要一致,并且至少8.0.17或者更高的版本。
donor 和 recipient的操作系统不能跨平台。
donor 和 recipient需要具有相同的字符集和排序规则。
donor和 recipient需要设置相同的 innodb_page_size and innodb_data_file_path
如果克隆了加密或者页压缩的数据,donor 和 recipient需要保持一样的文件系统块大小。
克隆命令将以1MB的包大小传输,所以donor 和 recipient的 max_allowed_packet至少要设置2MB。
2. 执行远程克隆命令
1. donor上创建用于克隆的MySQL用户,指定BACKUP_ADMIN权限
mysql> CREATE USER 'donor_clone_user'@'example.donor.host.com' IDENTIFIED BY 'password';
mysql> GRANT BACKUP_ADMIN on *.* to 'donor_clone_user'@'example.donor.hos
2.donor上安装Clone Plugin插件
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
3. recipient上创建用于克隆的MySQL用户,指定CLONE_ADMIN权限
(CLONE_ADMIN包含了BACKUP_ADMIN、SHUTDOWN权限)
mysql> CREATE USER 'recipient_clone_user'@'example.recipient.host.com' IDENTIFIED BY 'password';
mysql> GRANT CLONE_ADMIN on *.* to 'recipient_clone_user'@'example.recipient.host.com';
4. recipient上安装Clone Plugin插件
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
5. recipient上设置donor列表参数
mysql> SET GLOBAL clone_valid_donor_list = 'example.donor.host.com:3306';
6. recipient上执行clone命令
CLONE INSTANCE FROM 'user'@'host':port
IDENTIFIED BY 'password'
[DATA DIRECTORY [=] 'clone_dir']
[REQUIRE [NO] SSL];
四、 停止正在进行的克隆操作
执行SQL命令:KILL QUERY PROCESS_ID
mysql> SELECT * FROM performance_schema.clone_statusG
*************************** 1. row ***************************
ID: 1
PID: 8
STATE: In Progress
BEGIN_TIME: 2019-07-15 11:58:36.767
END_TIME: NULL
SOURCE: LOCAL INSTANCE
DESTINATION: /path/to/clone_dir/
ERROR_NO: 0
ERROR_MESSAGE:
BINLOG_FILE:
BINLOG_POSITION: 0
GTID_EXECUTED:
mysql> kill query 8;
五、其他注意事项
克隆操作期间不允许DDL(包括TRUNCATE TABLE)。
一次只能克隆一个MySQL实例。不支持在单个克隆操作中克隆多个MySQL实例。
远程克隆操作(在CLONE INSTANCE语句中指定Donor的MySQL服务器实例的端口号时)不支持mysqlx_port指定的X协议端口。
clone插件不支持MySQL配置参数的克隆。
clone插件不支持二进制日志的克隆。
克隆插件仅克隆存储在InnoDB中的数据。其他存储引擎数据未克隆。存储在任何数据库(包括sys模式)中的MyISAM和CSV表都被克隆为空表。
由叶老师主讲的知数堂「MySQL优化课」第17期已发车,课程从第15期就升级成MySQL 8.0版本了,现在上车刚刚好,扫码开启MySQL 8.0的修行之旅吧。
另外,叶老师在腾讯课堂《MySQL性能优化》精编版第一期已完结,本课程讲解读几个MySQL性能优化的核心要素:合理利用索引,降低锁影响,提高事务并发度。
下面是自动拼团的二维码,组团价仅需78元