一、MySQL 8.0.17的克隆clone简介二、初始化主从复制环境三、使用clone技术搭建主从复制 3.1 主库创建复制用户 3.2 主库和从库都安装克隆插件 3.3 从库开始克隆 3.4 查看clone进度和状态四、配置并启动主从复制五、测试主从同步六、总结
MySQL 8.0.17的克隆插件允许在本地或从远程 MySQL 实例在线克隆数据,从此搭建从库可以不再需要备份工具(PXB或mysqldump)来实现了。克隆数据是存储在 InnoDB 其中的数据的物理快照,其中包括库、表、表空间和数据字典元数据。克隆的数据包含一个功能齐全的数据目录,允许使用克隆插件进行 MySQL 服务器配置。
克隆插件支持两种克隆方式:
本地克隆:本地克隆操作将启动克隆操作的 MySQL 服务器实例中的数据克隆到同服务器或同节点上的一个目录里。
远程克隆:默认情况下,远程克隆操作会删除接受者(recipient)数据目录中的数据,并将其替换为捐赠者(donor)的克隆数据。(可选)您也可以将数据克隆到接受者的其他目录,以避免删除现有数据。
远程克隆操作和本地克隆操作克隆的数据没有区别,数据是相同的。克隆插件支持复制。除克隆数据外,克隆操作还从捐赠者中提取并传输复制位置信息,并将其应用于接受者,从而可以使用克隆插件来配置组复制或主从复制。使用克隆插件进行配置比复制大量事务要快得多,效率更高。
官网地址:https://dev.mysql.com/doc/refman/8.0/en/clone-plugin.html
Mater: 192.168.68.168 port:3306 doner 捐赠者
Slave: 192.168.68.169 port:3306 recipient 接受者
1-- 下载镜像 2docker pull mysql:8.0.20 3 4-- 创建主从网络环境 5docker network create --subnet=192.168.68.0/16 mhalhr 6docker network inspect mhalhr 7 8-- 创建MySQL参数文件路径 9mkdir -p /etc/mysql/mysql8020M1/ 10mkdir -p /etc/mysql/mysql8020S1/ 11 12-- 删除已存在的容器 13docker rm -f mysql8020M1 14docker rm -f mysql8020S1 15 16-- 创建主库 17docker run -d --name mysql8020M1 -h mysql8020M1 -p 3318:3306 \ 18 -v /etc/mysql/mysql8020M1/conf:/etc/mysql/conf.d \ 19 -e MYSQL_ROOT_PASSWORD=lhr -e TZ=Asia/Shanghai \ 20 --network mhalhr --ip 192.168.68.168 \ 21 mysql:8.0.20 22 23-- 创建从库 24docker run -d --name mysql8020S1 -h mysql8020S1 -p 3319:3306 \ 25 -v /etc/mysql/mysql8020S1/conf:/etc/mysql/conf.d \ 26 -e MYSQL_ROOT_PASSWORD=lhr -e TZ=Asia/Shanghai \ 27 --network mhalhr --ip 192.168.68.169 \ 28 mysql:8.0.20 29 30-- 修改主从环境的参数文件 31cat > /etc/mysql/mysql8020M1/conf/my.cnf <<"EOF" 32[mysqld] 33default-time-zone = '+8:00' 34log_timestamps = SYSTEM 35skip-name-resolve 36log-bin 37server_id=80203318 38character_set_server=utf8mb4 39 40gtid_mode=on 41enforce_gtid_consistency=on 42 43binlog-ignore-db = mysql 44binlog-ignore-db = information_schema 45binlog-ignore-db = performance_schema 46binlog-ignore-db = sys 47replicate_ignore_db=information_schema 48replicate_ignore_db=performance_schema 49replicate_ignore_db=mysql 50replicate_ignore_db=sys 51 52default_authentication_plugin=mysql_native_password 53 54report_host = 192.168.68.168 55report_port = 3306 56 57EOF 58 59 60cat > /etc/mysql/mysql8020S1/conf/my.cnf <<"EOF" 61[mysqld] 62default-time-zone = '+8:00' 63log_timestamps = SYSTEM 64skip-name-resolve 65log-bin 66server_id=80203319 67character_set_server=utf8mb4 68 69gtid_mode=on 70enforce_gtid_consistency=on 71 72binlog-ignore-db = mysql 73binlog-ignore-db = information_schema 74binlog-ignore-db = performance_schema 75binlog-ignore-db = sys 76replicate_ignore_db=information_schema 77replicate_ignore_db=performance_schema 78replicate_ignore_db=mysql 79replicate_ignore_db=sys 80 81default_authentication_plugin=mysql_native_password 82 83report_host = 192.168.68.169 84report_port = 3306 85 86EOF 87 88 89 90 -- 添加网卡 91docker network connect bridge mysql8020M1 92docker network connect bridge mysql8020S1 93 94-- 重启主从环境 95docker restart mysql8020M1 mysql8020S1
最后结果:
1[root@docker35 ~]# docker ps 2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3ebe3b62a2358 mysql:8.0.20 "docker-entrypoint.s…" About a minute ago Up 1 second 33060/tcp, 0.0.0.0:3319->3306/tcp mysql8020S1 476140b04e2fd mysql:8.0.20 "docker-entrypoint.s…" 2 minutes ago Up 4 seconds 33060/tcp, 0.0.0.0:3318->3306/tcp mysql8020M1
创建复制用户:
1mysql -uroot -plhr -h192.168.68.168 -P3306 2create user repl@'%' identified with mysql_native_password by 'lhr'; 3grant all on *.* to repl@'%';
创建测试数据库:
1create database lhrdb1 charset utf8mb4; 2use lhrdb1; 3CREATE TABLE student ( 4 no VARCHAR(20) PRIMARY KEY, 5 name VARCHAR(20) NOT NULL, 6 sex VARCHAR(10) NOT NULL, 7 birthday DATE, -- 生日 8 class VARCHAR(20) -- 所在班级 9); 10INSERT INTO student VALUES('101', '曾华', '男', '1977-09-01', '95033'),('102', '匡明', '男', '1975-10-02', '95031'),('103', '王丽', '女', '1976-01-23', '95033'),('104', '李军', '男', '1976-02-20', '95033'),('105', '王芳', '女', '1975-02-10', '95031'),('106', '陆军', '男', '1974-06-03', '95031'),('107', '王飘飘', '男', '1976-02-20', '95033'),('108', '张全蛋', '男', '1975-02-10', '95031'),('109', '赵铁柱', '男', '1974-06-03', '95031'); 11select * from student;
查询结果:
1mysql> select * from student; 2+-----+-----------+-----+------------+-------+ 3| no | name | sex | birthday | class | 4+-----+-----------+-----+------------+-------+ 5| 101 | 曾华 | 男 | 1977-09-01 | 95033 | 6| 102 | 匡明 | 男 | 1975-10-02 | 95031 | 7| 103 | 王丽 | 女 | 1976-01-23 | 95033 | 8| 104 | 李军 | 男 | 1976-02-20 | 95033 | 9| 105 | 王芳 | 女 | 1975-02-10 | 95031 | 10| 106 | 陆军 | 男 | 1974-06-03 | 95031 | 11| 107 | 王飘飘 | 男 | 1976-02-20 | 95033 | 12| 108 | 张全蛋 | 男 | 1975-02-10 | 95031 | 13| 109 | 赵铁柱 | 男 | 1974-06-03 | 95031 | 14+-----+-----------+-----+------------+-------+ 159 rows in set (0.00 sec)
1mysql -uroot -plhr -h192.168.68.168 -P3306 2mysql -uroot -plhr -h192.168.68.169 -P3306 3select plugin_name, plugin_status from information_schema.plugins where plugin_name = 'clone'; 4install plugin clone soname 'mysql_clone.so';
安装结果:
1mysql> select plugin_name, plugin_status from information_schema.plugins where plugin_name = 'clone'; 2+-------------+---------------+ 3| plugin_name | plugin_status | 4+-------------+---------------+ 5| clone | ACTIVE | 6+-------------+---------------+ 71 row in set (0.00 sec)
1-- 从库配置参数 2mysql -uroot -plhr -h192.168.68.169 -P3306 3set global clone_valid_donor_list='192.168.68.168:3306'; 4 5-- 从库开始克隆 6clone instance from root@'192.168.68.168':3306 identified by 'lhr';
执行过程:
1mysql> set global clone_valid_donor_list='192.168.68.168:3306'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> clone instance from root@'192.168.68.168':3306 identified by 'lhr'; 5ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process). 6mysql>
注意:默认情况下,克隆数据后会自动重新启动接受者 MySQL 实例。要自动重新启动,必须在接收方上提供监视进程以检测服务器是否已关闭。否则,在克隆数据后,克隆操作将停止并出现以下错误,并且关闭接受者 MySQL 服务器实例。此错误不表示克隆失败。这意味着必须在克隆数据后手动重新启动接受者的 MySQL 实例。
1ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process).
由于我们这里的环境是docker容器,所以只需要重新启动容器即可:
1docker start mysql8020S1
1mysql> select 2 -> stage, 3 -> state, 4 -> cast(begin_time as DATETIME) as "START TIME", 5 -> cast(end_time as DATETIME) as "FINISH TIME", 6 -> lpad(sys.format_time(power(10,12) * (unix_timestamp(end_time) - unix_timestamp(begin_time))), 10, ' ') as DURATION, 7 -> lpad(concat(format(round(estimate/1024/1024,0), 0), "MB"), 16, ' ') as "Estimate", 8 -> case when begin_time is NULL then LPAD('%0', 7, ' ') 9 -> when estimate > 0 then 10 -> lpad(concat(round(data*100/estimate, 0), "%"), 7, ' ') 11 -> when end_time is NULL then lpad('0%', 7, ' ') 12 -> else lpad('100%', 7, ' ') 13 -> end as "Done(%)" 14 -> from performance_schema.clone_progress; 15+-----------+-----------+---------------------+---------------------+------------+------------------+---------+ 16| stage | state | START TIME | FINISH TIME | DURATION | Estimate | Done(%) | 17+-----------+-----------+---------------------+---------------------+------------+------------------+---------+ 18| DROP DATA | Completed | 2020-11-04 10:11:14 | 2020-11-04 10:11:14 | 302.88 ms | 0MB | 100% | 19| FILE COPY | Completed | 2020-11-04 10:11:14 | 2020-11-04 10:11:16 | 1.38 s | 63MB | 100% | 20| PAGE COPY | Completed | 2020-11-04 10:11:16 | 2020-11-04 10:11:16 | 104.43 ms | 0MB | 100% | 21| REDO COPY | Completed | 2020-11-04 10:11:16 | 2020-11-04 10:11:16 | 101.02 ms | 0MB | 100% | 22| FILE SYNC | Completed | 2020-11-04 10:11:16 | 2020-11-04 10:11:18 | 2.12 s | 0MB | 100% | 23| RESTART | Completed | 2020-11-04 10:11:18 | 2020-11-04 10:11:44 | 26.02 s | 0MB | 100% | 24| RECOVERY | Completed | 2020-11-04 10:11:44 | 2020-11-04 10:11:45 | 1.19 s | 0MB | 100% | 25+-----------+-----------+---------------------+---------------------+------------+------------------+---------+ 267 rows in set (0.02 sec) 27 28mysql> SELECT * FROM performance_schema.clone_status \G 29*************************** 1. row *************************** 30 ID: 1 31 PID: 0 32 STATE: Completed 33 BEGIN_TIME: 2020-11-04 10:11:13.887 34 END_TIME: 2020-11-04 10:11:45.270 35 SOURCE: 192.168.68.168:3306 36 DESTINATION: LOCAL INSTANCE 37 ERROR_NO: 0 38 ERROR_MESSAGE: 39 BINLOG_FILE: mysql8020M1-bin.000004 40BINLOG_POSITION: 5993 41 GTID_EXECUTED: dcccf122-1e40-11eb-8ca0-0242c0a844a8:1-19 421 row in set (0.00 sec)
在从库执行:
1change master to master_host='192.168.68.168', 2master_port=3306, 3master_user='repl', 4master_password='lhr', 5master_auto_position=1; 6 7start slave; 8 9show slave status \G
结果:
1mysql> show slave status \G 2*************************** 1. row *************************** 3 Slave_IO_State: Waiting for master to send event 4 Master_Host: 192.168.68.168 5 Master_User: repl 6 Master_Port: 3306 7 Connect_Retry: 60 8 Master_Log_File: mysql8020M1-bin.000004 9 Read_Master_Log_Pos: 5993 10 Relay_Log_File: mysql8020S1-relay-bin.000002 11 Relay_Log_Pos: 436 12 Relay_Master_Log_File: mysql8020M1-bin.000004 13 Slave_IO_Running: Yes 14 Slave_SQL_Running: Yes 15 Replicate_Do_DB: 16 Replicate_Ignore_DB: information_schema,performance_schema,mysql,sys 17 Replicate_Do_Table: 18 Replicate_Ignore_Table: 19 Replicate_Wild_Do_Table: 20 Replicate_Wild_Ignore_Table: 21 Last_Errno: 0 22 Last_Error: 23 Skip_Counter: 0 24 Exec_Master_Log_Pos: 5993 25 Relay_Log_Space: 651 26 Until_Condition: None 27 Until_Log_File: 28 Until_Log_Pos: 0 29 Master_SSL_Allowed: No 30 Master_SSL_CA_File: 31 Master_SSL_CA_Path: 32 Master_SSL_Cert: 33 Master_SSL_Cipher: 34 Master_SSL_Key: 35 Seconds_Behind_Master: 0 36Master_SSL_Verify_Server_Cert: No 37 Last_IO_Errno: 0 38 Last_IO_Error: 39 Last_SQL_Errno: 0 40 Last_SQL_Error: 41 Replicate_Ignore_Server_Ids: 42 Master_Server_Id: 80203318 43 Master_UUID: dcccf122-1e40-11eb-8ca0-0242c0a844a8 44 Master_Info_File: mysql.slave_master_info 45 SQL_Delay: 0 46 SQL_Remaining_Delay: NULL 47 Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates 48 Master_Retry_Count: 86400 49 Master_Bind: 50 Last_IO_Error_Timestamp: 51 Last_SQL_Error_Timestamp: 52 Master_SSL_Crl: 53 Master_SSL_Crlpath: 54 Retrieved_Gtid_Set: 55 Executed_Gtid_Set: dcccf122-1e40-11eb-8ca0-0242c0a844a8:1-19 56 Auto_Position: 1 57 Replicate_Rewrite_DB: 58 Channel_Name: 59 Master_TLS_Version: 60 Master_public_key_path: 61 Get_master_public_key: 0 62 Network_Namespace:
主从复制配置成功。
主库建库建表:
1create database lhrdb2 charset utf8mb4; 2use lhrdb2; 3CREATE TABLE teacher ( 4 no VARCHAR(20) PRIMARY KEY, 5 name VARCHAR(20) NOT NULL, 6 sex VARCHAR(10) NOT NULL, 7 birthday DATE, 8 profession VARCHAR(20) NOT NULL, 9 department VARCHAR(20) NOT NULL 10); 11 12INSERT INTO teacher VALUES('804', '李诚', '男', '1958-12-02', '副教授', '计算机系'),('856', '张旭', '男', '1969-03-12', '讲师', '电子工程系'),('825', '王萍', '女', '1972-05-05', '助教', '计算机系'),('831', '刘冰', '女', '1977-08-14', '助教', '电子工程系'); 13select * from lhrdb2.teacher; 14 15mysql> select * from teacher; 16+-----+--------+-----+------------+------------+-----------------+ 17| no | name | sex | birthday | profession | department | 18+-----+--------+-----+------------+------------+-----------------+ 19| 804 | 李诚 | 男 | 1958-12-02 | 副教授 | 计算机系 | 20| 825 | 王萍 | 女 | 1972-05-05 | 助教 | 计算机系 | 21| 831 | 刘冰 | 女 | 1977-08-14 | 助教 | 电子工程系 | 22| 856 | 张旭 | 男 | 1969-03-12 | 讲师 | 电子工程系 | 23+-----+--------+-----+------------+------------+-----------------+ 244 rows in set (0.00 sec)
从库查询:
1mysql> select * from lhrdb2.teacher; 2+-----+--------+-----+------------+------------+-----------------+ 3| no | name | sex | birthday | profession | department | 4+-----+--------+-----+------------+------------+-----------------+ 5| 804 | 李诚 | 男 | 1958-12-02 | 副教授 | 计算机系 | 6| 825 | 王萍 | 女 | 1972-05-05 | 助教 | 计算机系 | 7| 831 | 刘冰 | 女 | 1977-08-14 | 助教 | 电子工程系 | 8| 856 | 张旭 | 男 | 1969-03-12 | 讲师 | 电子工程系 | 9+-----+--------+-----+------------+------------+-----------------+ 104 rows in set (0.00 sec)
可见,主从复制正常。
至此远程从库通过clone插件的方式搭建成功了,非常简单也非常快速,不需要mysqldump也不需要xtrabackup,在线搭建成功,非常快,以后用8.0可以考虑这种便捷的方式了。
克隆技术的一些限制条件:
版本大于等于8.0.17且不支持跨版本。要求相同版本号,您无法MySQL 5.7和MySQL 8.0之间进行克隆,在8.0.19和8.0.20之间也不可以,而且要求版本>=8.0.17。
克隆操作期间不允许使用 DDL,允许并发DML。
两台机器具有相同的操作系统OS。同一平台同一架构,例如linux to windows、x64 to x32 是不支持。
两台MySQL实例具体相同的 innodb_page_size 和 innodb_data_file_path(ibdata文件名)
同一时刻仅仅允许有一个克隆任务存在
recipient 需要设置变量clone_valid_donor_list
max_allowed_packet 大于2M
doner的undo表空间文件名称不能重复
不会克隆my.cnf文件
不会克隆binlog二进制日志。
仅仅支持innodb引擎。不克隆其他存储引擎数据。MyISAM并且 CSV存储在包括sys模式的任何模式中的表都被克隆为空表。
捐赠者和接受者都需要安装克隆插件
捐赠者和接受者分别需要有至少BACKUP_ADMIN/CLONE_ADMIN权限的账号
不支持通过MySQL router连接到捐赠者实例。
默认情况下,克隆数据后会自动重新启动接受者 MySQL 实例。要自动重新启动,必须在接收方上提供监视进程以检测服务器是否已关闭。否则,在克隆数据后,克隆操作将停止并出现以下错误,并且关闭接受者 MySQL 服务器实例。此错误不表示克隆失败。这意味着必须在克隆数据后手动重新启动接受者的 MySQL 实例。
1ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process).