Clone Plugin이 MySQL 8.0.17에 도입된 주요 기능을 소개합니다. 왜 이 기능을 구현해야 합니까? 개인적으로는 그룹복제를 주로 하는 것 같아요. 그룹 복제에서는 새로운 노드를 추가하고 분산 복구(Distributed Recovery)를 통해 차등 데이터를 완성합니다.
MySQL 8.0.17 이전에는 Binlog라는 한 가지 복구 방법만 지원되었습니다. 하지만 새 노드에 필요한 Binlog가 제거된 경우 현재로서는 백업 도구(XtraBackup, mydumper, mysqldump)를 사용하여 전체 데이터 양을 동기화한 후 분산 복구를 통해 증분 데이터를 동기화할 수 있습니다.
이 방법은 노드 추가 목적도 달성할 수 있지만 여전히 외부 도구의 도움이 필요하므로 일정량의 작업과 사용량 임계값이 필요합니다. 경쟁사인 PXC는 상태 스냅샷 전송(전체 동기화와 유사)을 위해 기본적으로 XtraBackup을 통합하는 반면 MongoDB는 한 단계 더 나아가 전체 데이터를 동기화하기 위해 기본적으로 초기 동기화를 구현한다는 점을 알아야 합니다. 사용 편의성의 관점에서 볼 때 MySQL은 클러스터에 노드를 추가하는 측면에서 경쟁사보다 열등합니다. 고객 경험 측면에서는 아직 개선의 여지가 많습니다.
다행히 MySQL 관계자도 이러한 격차를 인식하고 마침내 MySQL 8.0.17에 Clone Plugin을 구현했습니다. 물론 공무원들에게는 이 기능을 구현하는 것이 어렵지 않습니다. 결국 참고할 수 있는 기성 물리적 백업 도구(MySQL Enterprise Backup)가 있습니다.
이 글은 다음과 같은 측면에서 시작됩니다.
- 복제 플러그인 설치
- 복제 플러그인 사용
- 복제 작업 진행 상황을 확인하는 방법
- 복제 데이터를 기반으로 슬레이브 라이브러리를 구축하는 방법
- 구현 복제 플러그인 세부 정보
- 복제 플러그인의 제한 사항
- 복제 플러그인과 XtraBackup의 비교
- 복제 플러그인의 매개변수 분석
복제 플러그인은 다음 두 가지 설치 방법을 지원합니다.
( 1) 구성 파일 사양
[mysqld] plugin-load-add=mysql_clone.so clone=FORCE_PLUS_PERMANENT复制代码
여기서 클론은 엄밀히 말하면 매개 변수 이름이 아니라 추가할 수 있는 플러그인 이름으로, FORCE_PLUS_PERMANENT가 플러그인의 동작을 제어합니다.
네 가지 값이 있습니다:
(2) 동적 로딩
[mysqld] plugin-load-add=mysql_clone.so clone=FORCE_PLUS_PERMANENT复制代码
플러그인이 성공적으로 설치되었는지 확인하세요.
mysql> show plugins; ... | clone | ACTIVE | CLONE | mysql_clone.so | GPL | ...复制代码
클론 상태가 "ACTIVE"로 표시되는데, 이는 플러그인이 성공적으로 로딩되었음을 의미합니다.
복제 플러그인은 로컬 복제와 원격 복제의 두 가지 복제 방법을 지원합니다.
로컬 복제는 인스턴스에서 로컬로 시작되며 구문은 다음과 같습니다.
CLONE LOCAL DATA DIRECTORY [=] 'clone_dir';复制代码
그 중 clone_dir은 복제 디렉터리입니다.
아래에서 특정 데모를 살펴보세요.
복제 사용자 만들기
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_pass mysql> clone local data directory='/data/mysql/3307';复制代码
그 중 "/data/mysql/3307"이 복제 디렉터리로 다음 요구 사항을 충족해야 합니다.
- 복제 디렉터리는 절대 경로여야 합니다.
- "/data/mysql"이 존재해야 하며 MySQL에는 이에 대한 쓰기 권한이 있습니다.
- 3307은 존재할 수 없습니다.
복제 디렉터리 내용 보기
# ll /data/mysql/3307 total 172996 drwxr-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_logfile1 drwxr-x--- 2 mysql mysql 6 May 24 22:37 mysql -rw-r----- 1 mysql mysql 25165824 May 24 22:37 mysql.ibd drwxr-x--- 2 mysql mysql 20 May 24 22:37 slowtech drwxr-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에 비해 준비할 필요가 없고 바로 시작할 수 있습니다.
# /usr/local/mysql/bin/mysqld --no-defaults --datadir=/data/mysql/3307 --user mysql --port 3307 &复制代码
원격 복제에는 두 개의 인스턴스가 포함됩니다. 그 중 복제할 인스턴스는 Donor이고, 복제된 데이터를 받는 인스턴스는 Recipient입니다. 복제 명령은 수신자에서 시작되어야 하며 구문은 다음과 같습니다.
CLONE INSTANCE FROM 'user'@'host':port IDENTIFIED BY 'password' [DATA DIRECTORY [=] 'clone_dir'] [REQUIRE [NO] SSL];复制代码
그 중 호스트와 포트는 복제할 인스턴스(Donor)의 IP와 포트이고, 사용자와 비밀번호는 복제 사용자와 비밀번호입니다. 위와 같이 Donor의 비밀번호와 backup_admin 권한이 필요합니다. clone_user를 생성했습니다.
DATA DIRECTORY는 백업 디렉터리를 지정합니다. 지정하지 않으면 기본적으로 수신자의 데이터 디렉터리에 복제됩니다.
REQUIRE [NO] SSL, SSL 통신 활성화 여부.
아래에서 구체적인 데모를 살펴보세요.
먼저 Donor 인스턴스에 복제 사용자를 생성하고 복제 플러그인을 로드합니다.
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은 복제 작업에 필요한 권한입니다.
다음으로 수신자 인스턴스에 복제 사용자를 생성하고 복제 플러그인을 로드합니다.
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_pass mysql> 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.000009 BINLOG_POSITION: 665197555 GTID_EXECUTED: 59cd4f8f-8fa1-11ea-a0fe-000c29f66609:1-560 1 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.000009 BINLOG_POSITION: 665197555 GTID_EXECUTED: 59cd4f8f-8fa1-11ea-a0fe-000c29f66609:1-560 1 row in set (0.06 sec)复制代码
这里,区分两种场景,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)复制代码
这里,同样要区分两种场景。
场景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中的信息自动建立复制,很多时候,这未必是我们的预期行为。
克隆操作可细分为以下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()销毁克隆对象。
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端口。
除此之外,在进行远程克隆时,还会进行如下检查:
ERROR 3864 (HY000): Clone Donor MySQL version: 8.0.20 is different from Recipient MySQL version 8.0.19.复制代码
ERROR 3634 (HY000): Too many concurrent clone operations. Maximum allowed - 1.复制代码
ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process).复制代码
1、在实现上,两者都有FILE COPY和REDO COPY阶段,但Clone Plugin比XtraBackup多了一个PAGE COPY,由此带来的好处是,Clone Plugin的恢复速度比XtraBackup更快。
2、XtraBackup没有Redo Archiving特性,有可能出现未拷贝的Redo日志被覆盖的情况。
3、GTID下建立复制,无需额外执行set global gtid_purged操作。
需要注意的是,如果在执行DDL时,有CLONE命令在执行,DDL同样会因获取不到备份锁被阻塞,只不过,DDL操作的等待时长由lock_wait_timeout参数决定,该参数的默认值为31536000s,即365天。
관련 무료 학습 권장사항: mysql 비디오 튜토리얼
위 내용은 MySQL 8 Clone Plugin의 새로운 기능을 살펴보세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!