最詳細的clone plugin 介紹

一、能夠實現的功能介紹

MySQL 8.0.17推出的clone plugin插件,利用克隆插件可以擴展實現:
SQL命令進行備份。
Slave節點快速搭建。
MGR節點快速擴充。

而克隆插件的基礎功能,可以理解爲:
可以對本身的實例的InnoDB數據,備份到本服務器的指定目錄中。(本地克隆:本地備份)
可以將遠程實例的InnoDB數據還原到當前的實例中。(遠端克隆:遠端備份 + 本實例自動還原)
可以將遠程實例的InnoDB數據還原到當前的實例的其他目錄中。(遠端克隆:遠端備份)

二、克隆插件介紹

克隆插件允許從本地或遠程的MySQL Server中克隆數據。克隆的數據是存儲在InnoDB中的schema(database)、table(表)、tablespaces(表空間)和data dictionary metadata(數據字典元數據)的物理快照。該物理快照實際上是一個功能完整的數據目錄,MySQL克隆插件可以使用該數據目錄來配置並恢復一個MySQL Server。

2.1克隆插件分爲本地clone和遠程clone:

本地克隆:指的是將數據從啓動克隆操作的MySQL Server克隆到該MySQL Server的主機上的一個指定目錄下
遠程克隆:涉及到啓動克隆操作的本地MySQL Server(稱爲"recipient",即,數據的接收者或接收方)和數據源所在的遠程MySQL Server(稱爲"donor",即,數據的提供者或發送方),在接收方上啓動遠程克隆操作時,克隆的數據會通過網絡從發送方傳輸到接收方。
默認情況下,遠程可能那個操作會刪除接收方數據目錄中的所有數據,並將其替換爲克隆的新數據。如果不希望接收方中的現有數據被刪除,你也可以在接收方中執行克隆操作時將克隆數據指定存放在其他目錄中

2.2克隆插件應用場景:

對於克隆的數據本身來說,本地克隆操作與遠程克隆操作沒有太大區別。
克隆插件支持在複製拓撲中使用。除了克隆數據外,克隆操作還能夠從發送方中提取和傳輸複製座標(二進制日誌的位置),並將其應用於接收方,也就是說,我們可以使用克隆插件來在組複製中添加新的組成員,也可以在主從複製拓撲中添加新的從庫。
與通過二進制日誌來複制大量事務相比,通過克隆插件要快得多,效率也更高(更多信息詳見"6、在複製拓撲中使用克隆")。組複製成員還可以配置使用克隆插件來作爲另一種恢復方法(如果不使用克隆插件,則必須使用基於二進制日誌的狀態傳輸進行數據恢復),當組成員和待加入組的Server都配置支持克隆插件時,待加入組的Server可以自行決定選擇一個更加高效的方式從種子成員中獲取數據。
有關更多信息,請參見《MySQL Group Replication for 8.0》."4.3.1 克隆用於分佈式恢復"。

2.3克隆插件支持克隆數據加密的和數據頁壓縮:

克隆插件支持克隆數據加密的和數據頁壓縮。詳情可參考"4、克隆加密數據"和“5、克隆壓縮數據"

2.4使用克隆功能須先安裝克隆插件:

有關安裝的說明,詳情可參考"三、安裝克隆插件"。有關克隆的命令,詳情可參考"四、克隆演示”。

三、安裝克隆插件

下面是mysql8.0.20二進制安裝和插件具體安裝過程:


[root@mysql-redis182 3307]# wget -P /data/soft https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz
[root@mysql-redis182 3307]# tar Jxf /data/soft/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz -C /usr/local/
[root@mysql-redis182 logs]# cd /usr/local/;ln -sv mysql-8.0.20-linux-glibc2.12-x86_64 mysql
[root@mysql-redis182 ~]# grep -w '/data/mysql/3307' /data/mysql/3307/my8.cnf 
datadir = /data/mysql/3307/data
slow_query_log_file = /data/mysql/3307/logs/slow.log
log-error = /data/mysql/3307/logs/error.log
log-bin = /data/mysql/3307/binlog/mysql-bin
innodb_undo_directory = /data/mysql/3307/undolog

[root@mysql-redis182 logs]# /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/3307/my8.cnf --initialize
開啓mysql_clone.so參數寫入配置文件;
[root@mysql-redis182 mysql]# grep clone /data/mysql/my8.cnf 
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT        ##啓動時加載插件並防止它在運行時被刪除,

 獲取到密碼:
[root@mysql-redis182 logs]# grep -w 'root@localhost' error.log |awk '{print $NF}'
nbspMeu*K4g1
[root@mysql-redis182 3307]# /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/3307/my8.cnf &
[1] 12614
[root@mysql-redis182 3307]# ss -lntup|grep 3306
tcp    LISTEN     0      1024     :::3306                 :::*                   users:(("mysqld",pid=12614,fd=35))
tcp    LISTEN     0      70       :::33060                :::*                   users:(("mysqld",pid=12614,fd=31))

修改密碼:
root@localhost [(none)]>alter user user() identified by 'rRt&8UiJpN3v7Cx'
root@localhost [(none)]>select version();
+-----------+
| version() |
+-----------+
| 8.0.20    |
+-----------+
1 row in set (0.00 sec)

開啓clone插件:

root@localhost [(none)]>INSTALL PLUGIN clone SONAME 'mysql_clone.so';

INSTALL PLUGIN語句可以加載插件,並將其註冊到mysql系統庫下的mysql.plugins表中,這樣在後續重啓MySQL Server時不需要重複使用--plugin-load-add選項來加載插件庫

驗證插件是否安裝完成,可以查看INFORMATION_SCHEMA.plugins表或者使用SHOW PLUGINS語句查看:

root@localhost [(none)]>SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone       | ACTIVE        |
+-------------+---------------+
1 row in set (0.00 sec)

卸載插件:UNINSTALL PLUGIN clone;

克隆插件參數寫入配置文件:
例如,要在啓動時加載插件並防止它在運行時被刪除,可以使用以下選項:
提示在初始化mysql8.0 前不要加入下面的參數,否則導致初始化報錯以及啓動mysql報錯
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT ##啓動時加載插件並防止它在運行時被刪除,

有關插件激活狀態的更多信息,請參見鏈接https://dev.mysql.com/doc/refman/8.0/en/plugin-loading.html#server-plugin-activating

四、克隆插件演示:

4.1克隆本地數據:

克隆插件支持用於在本地克隆數據的語法,即,將數據從本地(相同主機)的一個MySQL Server的數據目錄克隆到本地MySQL Server所在主機的一個指定目錄下,
使用克隆插件執行克隆本地數據的操作語法如下:
mysql> CLONE LOCAL DATA DIRECTORY [=] 'clone_dir';

要正確使用CLONE語法,必須先安裝克隆插件。有關安裝說明,請參見"前文"。
執行CLONE LOCAL DATA DIRECTORY語句需要用戶具有BACKUP_ADMIN權限,因此需要先授予操作用戶該權限,語句如下:

#語法:
mysql> CLONE LOCAL DATA DIRECTORY = '/path/to/clone_dir';

其中,clone_user是用於執行克隆操作的MySQL用戶。該用戶可以是在"."上(全局權限)具有BACKUP_ADMIN權限的任何MySQL用戶

mysql> GRANT BACKUP_ADMIN ON . TO 'clone_user'@'127.0.0.1' idnetified by 'sjdue2398uys'; 此語法在mysql8.0中不支持了

下面是正確的授權語法:

 create user clone_user@'127.0.0.1' identified by 'sjdue2398uys';flush privileges;
 GRANT BACKUP_ADMIN ON *.* TO clone_user@'127.0.0.1';
  grant all on *.* to clone_user@'127.0.0.1';
 [root@localhost mysql]# mysql -uclone_user -h127.0.0.1 -p'sjdue2398uys'
mysql> CLONE LOCAL DATA DIRECTORY = '/data/mysql/mydata_clone'; # 這是克隆的副本目錄

Query OK, 0 rows affected (36.46 sec)

#查看克隆目錄下的文件:

mysql>  system ls -lh /data/mysql/mydata_clone
總用量 5.1G
drwxr-x--- 2 mysql mysql 4.0K 5月   8 12:02 #clone
-rw-r----- 1 mysql mysql 5.6K 5月   8 12:01 ib_buffer_pool
-rw-r----- 1 mysql mysql 1.0G 5月   8 12:01 ibdata1
-rw-r----- 1 mysql mysql 2.0G 5月   8 12:02 ib_logfile0
-rw-r----- 1 mysql mysql 2.0G 5月   8 12:02 ib_logfile1
drwxr-x--- 2 mysql mysql 4.0K 5月   8 12:01 mysql
-rw-r----- 1 mysql mysql  24M 5月   8 12:01 mysql.ibd
drwxr-x--- 2 mysql mysql 4.0K 5月   8 12:01 sys
-rw-r----- 1 mysql mysql  10M 5月   8 12:01 undo_001
-rw-r----- 1 mysql mysql  10M 5月   8 12:01 undo_002

在上述操作語句中,"/path/to/clone_dir"是將數據克隆到本地目錄的絕對路徑。
該路徑中,"clone_dir"目錄不能事先存在(事先存在會報錯),但路徑前綴"/path/to/"必須事先存在。

另外,MySQL Server必須具有在文件系統中創建目錄所需的寫權限
注意:本地克隆操作不支持克隆位於數據目錄外部的用戶創建的表或表空間。
嘗試克隆此類表或表空間會導致報錯:

ERROR 1086 (HY000): File '/path/to/tablespace_name.ibd' already exists.。
克隆操作時如果指定了一個與數據源表空間相同路徑時會導致衝突,因此被禁止

重要提示:

當執行克隆操作時,所有用戶創建的InnoDB表和表空間,InnoDB系統表空間,redo log和undo log表空間都將被克隆到指定目錄下
注意:克隆操作只會克隆數據文件,除了系統變量datadir之外,
如果系統變量innodb_data_home_dir、innodb_data_file_path、innodb_log_group_home_dir、innodb_undo_directory單獨指定了不同於datadir指定的路徑,則也會被執行克隆,
系統變量socket、pid-file、tmpdir、log-error、slow_query_log_file、log-bin、relay-log指定路徑下的文件不會被克隆

如果需要,可以在克隆操作完成後使用克隆的數據目錄啓動一個新的MySQL Server,例如:

#其中clone_dir是克隆操作完成之後的數據副本目錄
shell> mysqld_safe --datadir=clone_dir

#示例
先將第二個MySQL Server的配置文件設置好,不能與同一個主機中其他MySQL Server的配置文件存在路徑衝突,也不能存在端口衝突,然後,使用mysqld_safe啓動第二MySQL Server,使用--datadir指定克隆的數據副本目錄。
由於原先的實例開啓了innodb_undo_directory 存放undolog的日誌,然而指定目錄/data/mysql/mydata_clone 克隆完成後,undolog日誌存放了/data/mysql/mydata_clone 這個下面,所以clonemy8.cnf配置文件要重新指定innodb_undo_directory=/data/mysql/mydata_clone,才能基於clone副本數據正常啓動新的實例

 mysqld_safe --defaults-file=/data/mysql/clonemy8.cnf --datadir=/data/mysql/mydata_clone &
 當然mysqld  --defaults-file=/data/mysql/clonemy8.cnf --datadir=/data/mysql/mydata_clone &  也可以啓動的

本地指定目錄克隆後,重啓新實例的mysql的配置文件需要修改的路徑如下:

 [root@localhost ~]# egrep '3307|mydata_clone' /data/mysql/clonemy8.cnf 
port    = 3307
socket  = /tmp/mysql3307.sock
port    = 3307
datadir = /data/mysql/mydata_clone
socket  = /tmp/mysql3307.sock
pid-file = mysqldb3307.pid
innodb_undo_directory = /data/mysql/mydata_clone

查看clone狀態:顯示的失敗,然而本地指定目錄clone,事實上是成功的
因爲指定DATA DIRECTORY,本地磁盤空間需要更多的空間(克隆數據+本地歷史數據),不會自動重啓MySQL實例


mysql> select * from performance_schema.clone_status;
+------+------+--------+-------------------------+----------+----------------+----------------+----------+-------------------------------------------------------------------------------+-------------+-----------------+---------------+
| ID   | PID  | STATE  | BEGIN_TIME              | END_TIME | SOURCE         | DESTINATION    | ERROR_NO | ERROR_MESSAGE                                                                 | BINLOG_FILE | BINLOG_POSITION | GTID_EXECUTED |
+------+------+--------+-------------------------+----------+----------------+----------------+----------+-------------------------------------------------------------------------------+-------------+-----------------+---------------+
|    1 |    0 | Failed | 2020-05-08 12:01:44.674 | NULL     | LOCAL INSTANCE | LOCAL INSTANCE |     1815 | Recovery failed. Please Retry Clone. For details, look into server error log. |             |               0 |               |
+------+------+--------+-------------------------+----------+----------------+----------------+----------+-------------------------------------------------------------------------------+-------------+-----------------+---------------+
1 row in set (0.00 sec)

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-08 12:01:44.674154 | 2020-05-08 12:01:44.674758 |       1 |          0 |          0 |       0 |          0 |             0 |
|    1 | FILE COPY | Completed | 2020-05-08 12:01:44.674812 | 2020-05-08 12:01:57.679768 |       2 | 1119999520 | 1119999520 |       0 |          0 |             0 |
|    1 | PAGE COPY | Completed | 2020-05-08 12:01:57.679858 | 2020-05-08 12:01:57.882701 |       2 |          0 |          0 |       0 |          0 |             0 |
|    1 | REDO COPY | Completed | 2020-05-08 12:01:57.882761 | 2020-05-08 12:01:58.084247 |       2 |       8192 |       8192 |       0 |          0 |             0 |
|    1 | FILE SYNC | Completed | 2020-05-08 12:01:58.084367 | 2020-05-08 12:02:21.137360 |       2 |          0 |          0 |       0 |          0 |             0 |
|    1 | RESTART   | Completed | 2020-05-08 12:02:21.137360 | 2020-05-08 12:17:37.276226 |       0 |          0 |          0 |       0 |          0 |             0 |
|    1 | RECOVERY  | Failed    | 2020-05-08 12:17:37.276226 | NULL                       |       0 |          0 |          0 |       0 |          0 |             0 |
+------+-----------+-----------+----------------------------+----------------------------+---------+------------+------------+---------+------------+---------------+
7 rows in set (0.00 sec)

mysql> 

提示:
手動啓動MySQL Server後,可以連接到接收方MySQL Server檢查performance_schema下的clone_progress和clone_status表,以驗證克隆操作是否成功完成。對於RESTART語句也會執行相同的監控

4.2 克隆遠程數據

4.2.1克隆遠程數據語法介紹:

克隆插件支持以下語法來克隆遠程數據,即,從遠程MySQL Server(數據捐贈者,或稱爲donor節點)克隆數據並將其傳輸到執行克隆操作的MySQL Server(數據接收者,或稱爲recipient節點)
CLONE INSTANCE FROM 'user'@'host':port IDENTIFIED BY 'password' [DATA DIRECTORY [=] 'clone_dir'] [REQUIRE [NO] SSL];

以上語法中的一些關鍵字解釋:
"user"是donor MySQL Server上的用於執行克隆操作的用戶,需要具有對所有庫所有表的BACKUP_ADMIN權限
"host"是donor MySQL Server的主機名或IP地址。不支持IPV6地址,但支持IPV6地址別名與IPV4地址
"port"是donor MySQL Server的端口號。(不支持mysqlx_port指定的X協議端口。也不支持通過MySQL Router連接到donor MySQL Server)
"password"是"user"的用戶密碼
"DATA DIRECTORY [=] 'clone_dir'" 是一個可選子句,用於在recipient節點上爲要克隆的數據副本指定一個本地存放目錄。
如果不希望刪除recipient節點上數據目錄中的現有數據,請使用此選項指定一個其他路徑。
但需要指定一個絕對路徑,並且該目錄不能事先存在、MySQL Server必須具有創建目錄所需的寫訪問權限。
如果在執行克隆操作時未使用可選的"DATA DIRECTORY [=] 'clone_dir'" 子句,則克隆操作將刪除recipient節點數據目錄中的現有數據,並用克隆數據副本來替換它,然後自動重新啓動MySQL Server
"[REQUIRE [NO] SSL]" 用於顯式指定在通過網絡傳輸克隆數據時是否使用加密連接。
如果使用了該子句但不能滿足SSL使用條件,則返回一個錯誤。
如果沒有指定SSL子句,則克隆數據時默認會先嚐試建立加密連接,但如果SSL連接嘗試失敗,則退回使用不安全連接。
另外,無論是否指定此子句,如果要克隆加密數據,則必須使用安全連接。
有關更多信息,請參見下文中"爲克隆配置加密連接"部分,原文鏈接:https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-remote.html#clone-plugin-remote-ssl

注意:
默認情況下,駐留在發送方(donor節點)MySQL Server的數據目錄中用戶創建的InnoDB表和表空間,會被克隆到接收方(recipient節點)MySQL Server的數據目錄中(接收方中與數據文件存放相關的系統變量指定的路徑下)。
如果指定了"DATA DIRECTORY [=] 'clone_dir'"子句,則在接收方中會將克隆數據存放到指定的目錄下
如果用戶創建的InnoDB表和表空間位於發送方MySQL Server的數據目錄之外,它們會被克隆到接收方MySQL Server的相同路徑上。

如果在接收方MySQL Server的相同路徑上存在相同文件(表或表空間文件),則會報錯.默認情況下,InnoDB的系統表空間、redo log和undo log表空間被克隆到與donor節點上的相關係統變量指定的相同位置
(分別由系統變量innodb_data_home_dir和innodb_data_file_path、innodb_log_group_home_dir和innodb_undo_directory指定)。
因此,如果未指定DATA DIRECTORY [=] 'clone_dir'子句,請確保donor節點和recipient節點中的相關係統變量設了爲相同路徑,如果指定了DATA DIRECTORY [=] 'clone_dir'子句,那麼這些表空間和日誌將被克隆到指定的目錄下
(但如果指定了克隆數據的存放目錄,則所有的數據文件都會被存放到該目錄下,因此,在使用這些集中存放的克隆數據文件來啓動新的MySQL Server之前,你可能需要手動做一些路徑調整)

4.2.2遠程克隆的前提條件:

要執行遠程克隆操作,克隆插件必須在發送方和接收方的MySQL Server上都是安裝且都處於激活狀態。有關安裝說明,請參見"安裝克隆插件"

執行遠程克隆操作需要在發送方和接收方上都創建好用於克隆操作的MySQL用戶(對於發送方和接收方上各自用戶克隆的用戶,其用戶名和密碼可以不相同),且授予足夠的權限

  • 對於發送方,克隆用戶需要BACKUP_ADMIN權限來訪問和傳輸發送方的數據,並在克隆操作期間阻塞DDL操作
  • 對於接收方,克隆用戶需要CLONE_ADMIN權限來替換接收方的數據,並在克隆操作期間阻塞DDL操作,並自動重新啓動MySQL Server。
    注意:CLONE_ADMIN權限隱式地包含了BACKUP_ADMIN和SHUTDOWN權限。當執行遠程克隆操作時(執行CLONE INSTANCE語句)會執行一些前提條件檢查:

    • 發送方和接收方必須擁有相同的MySQL Server版本。注意:MySQL 8.0.17及更高版本支持克隆插件,低於MySQL 8.0.17版本不支持,可以使用:SELECT VERSION()語句查看版本號
    • 發送方和接收方MySQL Server必須運行在相同的操作系統和平臺上。
      例如,如果donor節點運行在一個Linux 64位平臺上,那麼recipient節點也必須運行在Linux 64位平臺上。有關如何確定操作系統平臺的信息,請參閱操作系統相關文檔
    • 接收方必須有足夠的磁盤空間來存放克隆數據。默認情況下,在接收方中接收發送方的克隆數據之前會先刪除接收方的數據,因此只需要按照發送方的數據大小來提供足夠的磁盤空間即可。
      但如果使用了DATA DIRECTORY [=] 'clone_dir'子句將克隆數據存放到指定的目錄下,則必須考慮接收方和發送方的數據總大小,以便提供足夠存放兩者數據大小的磁盤空間。
      可以通過檢查文件系統上的數據目錄大小和位於數據目錄之外的任何表空間的大小來估計數據的大小。在估計發送方的數據大小時,請記住只有InnoDB數據是克隆的。
      如果在其他存儲引擎中存儲了數據,在估算克隆所需的磁盤空間時請注意排除這些數據文件的大小
  • InnoDB允許在數據目錄(datadir系統變量指定的目錄)之外創建一些表空間類型。如果發送方MySQL Server有駐留在數據目錄之外的表空間,則克隆操作必須能夠訪問這些表空間。
    可以通過查詢INFORMATION_SCHEMA.FILES表來識別位於數據目錄之外的數據表空間有哪些,駐留在數據目錄之外的數據表空間文件是一個絕對路徑。
    查詢語句:SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES

    root@localhost [(none)]>SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES;
    +-----------------------------------+
    | FILE_NAME                         |
    +-----------------------------------+
    | ./ibdata1                         |
    | ./ibtmp1                          |
    | /data/mysql/3307/undolog/undo_001 |
    | /data/mysql/3307/undolog/undo_002 |
    | ./mysql.ibd                       |
    | ./sys/sys_config.ibd              |
    +-----------------------------------+
    6 rows in set (0.00 sec)
    • 在發送方上處於激活狀態的任何插件,也必須在接收方上處於活動狀態。可以通過執行SHOW plugins語句或查詢INFORMATION_SCHEMA.PLUGINS表來識別活躍狀態的插件
    • 發送方和接收方必須具有相同的MySQL Server字符集和排序規則。有關MySQL Server字符集和排序配置的信息,請參閱:https://dev.mysql.com/doc/refman/8.0/en/charset-configuration.html
    • 發送方和接收方需要具有相同的innodb_page_size和innodb_data_file_path系統變量設置。在發送方和接收方上的innodb_data_file_path系統變量設置必須指定相同數量、相同大小的數據文件。
      可以使用SHOW VARIABLES語句檢查各自的變量設置值。例如:SHOW VARIABLES LIKE 'innodb_page_size';SHOW VARIABLES LIKE 'innodb_data_file_path';

    • 如果克隆加密數據或壓縮頁數據,則發送方和接收方必須具有相同的文件系統塊大小。
      對於頁壓縮數據,接收方的文件系統必須支持稀疏文件和打孔(文件系統的概念,可參考鏈接:http://www.voidcn.com/article/p-cwkauntz-bpz.html),以便在接收方的文件系統上打孔
      有關這些特性以及如何識別使用它們的表和表空間的信息,請參見下文中的"4、克隆加密數據"和"5、克隆壓縮數據"。要確定文件系統塊大小,請參閱操作系統相關的文檔。

    • 如果要克隆加密數據,則需要啓用安全連接。請參見下文中"爲克隆配置加密連接"部分

    • 接收方上的系統變量clone_valid_donor_list的設置必須包含donor MySQL Server的主機地址。因爲只能從有效的接收方列表中的主機克隆數據。
      如果要設置該系統變量,則需要用戶具有SYSTEM_VARIABLES_ADMIN權限。在本節後面的遠程克隆示例中提供了設置clone_valid_donor_list系統變量的說明。
      可以使用SHOW VARIABLES語句檢查clone_valid_donor_list系統變量的設置。例如:SHOW VARIABLES LIKE 'clone_valid_donor_list'

    • 克隆操作只能串行執行,不能多個克隆操作並行執行,要確定是否有克隆操作正在運行,可以通過查詢performance_schema.clone_status表進行確認,詳情可參考"9、監控克隆操作"
    • 克隆插件以1MB大小的數據包和1M大小的元數據的形式傳輸數據。因此,在發送方和接收方的MySQL Server上,max_allowed_packet變量的最小值要求爲2MB。
      小於2MB的max_allowed_packet變量值會導致報錯。可以使用查詢語句來檢查max_allowed_packet變量的設置:SHOW VARIABLES LIKE 'max_allowed_packet'

    以下前提條件也適用於遠程克隆操作:

    • UNDO表空間文件名必須是唯一的。當數據被從發送方克隆到接收方時,無論UNDO表空間在發送方上的什麼位置下存放着,都會被克隆到接收方上的innodb_undo_directory系統變量指定的位置,或者被克隆到DATA DIRECTORY [=] 'clone_dir'子句指定的目錄下(如果使用該子句的話)。
      從MySQL 8.0.18開始,如果在克隆操作期間遇到重複的undo表空間文件名,就會報告錯誤。在MySQL 8.0.18之前,克隆具有相同文件名的undo表空間可能會導致接收方上的undo表空間文件被覆蓋。

    • 要查看UNDO表空間文件名以確保它們的名稱是唯一的,可以通過查詢INFORMATION_SCHEMA.FILES表,例如:SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE LIKE 'UNDO LOG'

    • 有關刪除和添加undo表空間文件的信息,請參閱:https://dev.mysql.com/doc/refman/8.0/en/innodb-undo-tablespaces.html

    • 默認情況下,在克隆數據完成之後,將自動重新啓動(停止和啓動)接收方MySQL Server。
      要實現自動重啓,必須在接收方上有一個監控進程來檢測Server關閉。
      否則,在數據被克隆後、克隆操作停止、並關閉了接收方MySQL Server之後會報錯:ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process)。
      此錯誤不表示克隆操作失敗。這意味着在克隆數據之後,必須手動啓動接收方MySQL Server。
      手動啓動MySQL Server後,可以連接到接收方MySQL Server檢查performance_schema下的clone_progress和clone_status表,以驗證克隆操作是否成功完成。
      對於RESTART語句也會執行相同的監控。有關更多信息,請參見:https://dev.mysql.com/doc/refman/8.0/en/restart.html
      如果使用DATA DIRECTORY [=] 'clone_dir'子句克隆到指定目錄,則不適用此要求,因爲在此情況下不會執行自動重新啓動MySQL Server
      (指定克隆目錄的情況下,所有數據文件都被拷貝到了該目錄下,實際啓動MySQL Server時,配置文件中可能將redo log、undo log和數據文件指向了不同的路徑)

    • 克隆插件支持多個系統變量用於控制遠程克隆操作。在執行遠程克隆操作之前,請檢查系統變量並根據需要進行調整以適應你的運行環境。
      克隆相關的系統變量是在執行克隆操作的MySQL Server上設置的(接收方)。參見"12、克隆插件系統變量"

    克隆遠程數據操作示例:默認情況下,遠程克隆操作會刪除接收方數據目錄中的數據,用克隆的數據替換,然後重新啓動MySQL Server
    (但指定了DATA DIRECTORY [=] 'clone_dir'子句時不會執行自動重啓),該示例假設已經滿足了所有的前提條件呢,詳情參見上文

4.2.4、遠程克隆數據:
環境:
192.168.1.105 master實例
192.168.1.182 新的實例
安裝過程可以參考“三、安裝克隆插件”,此處不再贅述。

開始操作演示:
192.168.1.105 機器發送端操作:

 使用管理用戶登錄到發送方 donor MySQL Server中,創建一個克隆用戶並賦予BACKUP_ADMIN權限:
 root@localhost [(none)]> create user donor_clone_user@'192.168.1.%' identified by 'clone_test66';
Query OK, 0 rows affected (0.02 sec)

root@localhost [(none)]>grant backup_admin on *.* to donor_clone_user@'192.168.1.%';
Query OK, 0 rows affected (0.02 sec)

在donor MySQL Server中安裝克隆插件:
root@localhost [(none)]>INSTALL PLUGIN clone SONAME 'mysql_clone.so';
ERROR 1125 (HY000): Function 'clone' already exists

192.168.1.182接受方機器操作:

使用管理用戶登錄到接收方MySQL Server,創建一個克隆用戶並賦予CLONE_ADMIN權限:

root@localhost [(none)]>create user recipient_clone_user@'192.168.1.%' identified by 'clone_test66';
root@localhost [(none)]>grant clone_admin on *.* to recipient_clone_user@'192.168.1.%';
在接收方MySQL Server中安裝克隆插件:
root@localhost [(none)]>INSTALL PLUGIN clone SONAME 'mysql_clone.so';
ERROR 1125 (HY000): Function 'clone' already exists

將donor MySQL Server的主機地址添加到接收方MySQL Server的clone_valid_donor_list變量中:
root@localhost [(none)]> SET GLOBAL clone_valid_donor_list = '192.168.1.105:3306';
以在donor MySQL Server中創建的克隆用戶,登錄到接收方MySQL Server中,執行如下克隆語句:(指定克隆目錄操作)
root@localhost [(none)]>CLONE INSTANCE FROM 'donor_clone_user'@'192.168.1.105':3306 IDENTIFIED BY 'clone_test66' DATA DIRECTORY = '/data/mysql/3307/clone_data';
Query OK, 0 rows affected (24.72 sec)

查看克隆狀態:
root@localhost [performance_schema]>select * from clone_status\G
*************************** 1. row ***************************
             ID: 1
            PID: 9
          STATE: Completed
     BEGIN_TIME: 2020-05-08 16:34:20.646
       END_TIME: 2020-05-08 16:34:45.358
         SOURCE: 192.168.1.105:3306
    DESTINATION: /data/mysql/3307/clone_data/
       ERROR_NO: 0
  ERROR_MESSAGE: 
    BINLOG_FILE: 
BINLOG_POSITION: 0
  GTID_EXECUTED: 
1 row in set (0.00 sec)

root@localhost [performance_schema]>select * from clone_progress;
+------+-----------+-------------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
| ID   | STAGE     | STATE       | BEGIN_TIME                 | END_TIME                   | THREADS | ESTIMATE   | DATA       | NETWORK    | DATA_SPEED | NETWORK_SPEED |
+------+-----------+-------------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
|    1 | DROP DATA | Completed   | 2020-05-08 16:34:20.769263 | 2020-05-08 16:34:20.871097 |       1 |          0 |          0 |          0 |          0 |             0 |
|    1 | FILE COPY | Completed   | 2020-05-08 16:34:20.871379 | 2020-05-08 16:34:31.474627 |       4 | 1119999445 | 1119999445 | 1120067369 |          0 |             0 |
|    1 | PAGE COPY | Completed   | 2020-05-08 16:34:31.474938 | 2020-05-08 16:34:31.776621 |       4 |          0 |          0 |        393 |          0 |             0 |
|    1 | REDO COPY | Completed   | 2020-05-08 16:34:31.777004 | 2020-05-08 16:34:32.077628 |       4 |       2560 |       2560 |       3325 |          0 |             0 |
|    1 | FILE SYNC | Completed   | 2020-05-08 16:34:32.077900 | 2020-05-08 16:34:45.357769 |       4 |          0 |          0 |          0 |          0 |             0 |
|    1 | RESTART   | Not Started | NULL                       | NULL                       |       0 |          0 |          0 |          0 |          0 |             0 |
|    1 | RECOVERY  | Not Started | NULL                       | NULL                       |       0 |          0 |          0 |          0 |          0 |             0 |
+------+-----------+-------------+----------------------------+----------------------------+---------+------------+------------+------------+------------+---------------+
7 rows in set (0.00 sec)

克隆到指定目錄說明:
默認情況下,遠程克隆操作會刪除接收方數據目錄中的數據,並用克隆的數據替換它。
通過克隆到指定目錄,可以避免接收方數據目錄中的現有數據被刪除,也不會執行重啓MySQL Server的操作。
將數據克隆到指定目錄的過程與不指定目錄的克隆遠程數據過程相同,但有一點區別,前者的克隆語句必須包含DATA DIRECTORY [=] 'clone_dir'子句。
例如:CLONE INSTANCE FROM 'donor_clone_user'@'192.168.1.105':3306 IDENTIFIED BY 'clone_test66' DATA DIRECTORY = '/data/mysql/3307/clone_data';
其中,DATA DIRECTORY子句需要指定一個絕對路徑,且該目錄不能事先存在,MySQL Server必須具有創建目錄所需的寫訪問權限

克隆到指定目錄時,在克隆數據完成之後,不會自動重新啓動接收方MySQL Server。
如果你想使用指定目錄啓動MySQL Server,你必須手動修改一些文件的目錄調整之後再執行啓動,或者直接使用新的my.cnf配置文件,
在啓動時將--datadir選項指定到克隆數據所在的目錄,例如:mysqld_safe --datadir=/data/mysql/3307/clone_data
由於配置文件制定了undo文件存放目錄,所以也要修改下:

[root@mysql-redis182 ~]# grep -w 'clone_data' /data/mysql/3307/my8.cnf 
datadir = /data/mysql/3307/clone_data
innodb_undo_directory = /data/mysql/3307/clone_data

然後啓動mysql服務:


/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/3307/my8.cnf & 
登錄192.168.1.182 發現主庫192.168.1.105上創建的數據已經clone本地了
root@localhost [(none)]>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test001            |
| test002            |
+--------------------+
6 rows in set (0.01 sec)

root@localhost [(none)]>select user,host from mysql.user;
+------------------+-------------+
| user             | host        |
+------------------+-------------+
| donor_clone_user | 192.168.1.% |
| mysql.infoschema | localhost   |
| mysql.session    | localhost   |
| mysql.sys        | localhost   |
| root             | localhost   |
+------------------+-------------+
5 rows in set (0.00 sec)

啓動克隆版的MySQL,查看接受放的二進制日誌位置和gtid信息:

克隆操作結束之後,可在執行克隆操作的MySQL Server上執行如下查詢語句,以檢查發送給接收方的二進制日誌位置:

root@localhost [(none)]>SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
+------------------+-----------------+
| BINLOG_FILE      | BINLOG_POSITION |
+------------------+-----------------+
| mysql-bin.000002 |            2463 |
+------------------+-----------------+
1 row in set (0.01 sec)

在克隆操作結束之後,可在執行克隆操作的MySQL Server上執行如下查詢,以檢查傳輸給接收方的GTID SET:

root@localhost [(none)]>SELECT @@GLOBAL.GTID_EXECUTED;
+------------------------------------------------------------------------------------+
| @@GLOBAL.GTID_EXECUTED                                                             |
+------------------------------------------------------------------------------------+
| e03f6a3a-90f8-11ea-9e29-842b2b72175e:1-9,
fb9ad95e-9104-11ea-ab74-b82a72cec95c:1-3 |
+------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

提示:當在192.168.1.182機器接受端未指定克隆目錄操作,會清空當前192.168.1.182mysql實例數據目錄下的數據,然後把克隆的數據複製過來,並且會自動重啓mysql服務,由於undolog日誌路徑變化導致重啓失敗
登錄到接收方192.168.1.182MySQL Server中,執行如下克隆語句:(未指定克隆目錄操作)
root@localhost [(none)]> CLONE INSTANCE FROM 'donor_clone_user'@'192.168.1.105':3306 IDENTIFIED BY 'clone_test66' ;
ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process).

五、利用遠程克隆的數據進行復制拓撲擴展應用介紹:

當在發送方上設置master_info_repository=TABLE和relay_log_info_repository=TABLE時(這是MySQL 8.0的默認設置),如果發送方是一個從庫角色,那麼從庫的狀態日誌會被保存在表中,這些表在克隆操作期間會從發送方當做數據複製到接收方。
從庫的狀態日誌中保存了與複製相關的配置設置,這些設置可用於在克隆操作成功之後正確地自動恢復複製
(如果配置文件中沒有設置skip_slave_start參數,則在克隆操作完成之後會自動啓動複製線程,另外,如果發送方不是從庫而是主庫,那麼從庫的狀態日誌表中並不存在複製配置信息,因此不適用,恢復複製過程中需要手動執行CHANGE MASTER語句進行配置)。

在MySQL 8.0.17和8.0.18中,只有mysql.slave_master_info表纔會被複制到接收方(主庫信息日誌)
從MySQL 8.0.19開始,mysql.slave_relay_log_info(中繼日誌信息日誌)和mysql.slave_worker_info(從庫worker線程日誌)也會被複制到接收方
PS:有關上述三張表中每個表包含的內容列表及其含義,請參閱:https://dev.mysql.com/doc/refman/8.0/en/slave-logs-status.html
注意,如果在發送方上設置了master_info_repository=FILE和relay_log_info_repository=FILE(這不是MySQL 8.0的默認設置,並且是不推薦的),則不會克隆從庫的狀態日誌,只有在發送方設置master_info_repository=TABLE和relay_log_info_repository=TABLE時纔會克隆從庫的狀態日誌信息。

要在複製拓撲中使用克隆,請按照以下步驟執行:
對於用於組複製的新組成員,請先按照鏈接:https://dev.mysql.com/doc/refman/8.0/en/group-replication-adding-instances.html 中的說明爲組複製配置好MySQL Server環境,且按照鏈接:https://dev.mysql.com/doc/refman/8.0/en/group-replication-cloning.html的說明設置好克隆功能所需的前提條件
然後,在joiner成員上執行START GROUP_REPLICATION語句時,克隆操作由組複製自動管理,因此不需要手動執行joiner成員加入組的操作,也不需要在joiner成員上執行任何進一步的設置步驟。

對於主從複製拓撲中的從庫,首先在從庫(接收方)中手動執行遠程克隆操作語句,將數據從donor MySQL Server克隆到接收方。
在複製拓撲中,發送方必須是主庫或從庫。如果發送方是主庫的,則後續需要手動執行CHANGE MASTER語句來配置複製,如果發送方是從庫的,則不需要手動執行復制配置操作,複製能夠通過克隆數據進行自動恢復複製
(配置文件中指定了skip_slave_start參數的情況除外)。有關克隆語句的詳細信息,請參見"3、克隆遠程數據"

克隆操作成功完成後,如果要在接收方MySQL Server上使用與發送方相同的複製通道,請驗證其中哪些設置或配置可以在主從複製拓撲中自動恢復,哪些需要手動設置才能恢復。

  • 對於基於GTID的複製,如果在接收方配置了gtid_mode=ON,並且在發送方設置了gtid_mode=ON、ON_PERMISSIVE或 OFF_PERMISSIVE值,則接收方的gtid_executed系統變量中的GTID SET會作爲接收方的GTID SET。
    如果接收方的數據是從拓撲中已經存在的一個從庫中克隆出來的,則在啓用了GTID自動定位(由CHANGE MASTER TO語句上的MASTER_AUTO_POSITION選項指定)的接收方上的複製通道可以在自動重啓MySQL Server之後自動恢復,不需要執行任何手動設置(如果需要修改複製通道,則自行調整,這裏不做贅述)

  • 對於基於二進制日誌文件位置的複製,如果接收方使用的是MySQL 8.0.17或8.0.18,則來自發送方的二進制日誌位置不應用於接收方,僅記錄在performance_schema.clone_status表中。
    因此,在自動重啓實例之後,必須在接收方中手動爲複製通道設置使用基於二進制日誌文件位置的複製,以便恢復複製。
    在這種情況下,需要確保在重啓實例時啓用skip_slave_start來避免複製自動啓動,因爲此時並未設置二進制日誌位置,自動啓動複製將嘗試從頭開始複製。

  • 對於基於二進制日誌文件位置的複製,如果接收方使用的是MySQL 8.0.19或以上版本,則來自發送方的二進制日誌位置將應用於接收方。
    接收方上使用基於二進制日誌文件位置的複製,將會在自動重啓複製通道之前,使用中繼日誌信息自動嘗試執行中繼日誌的恢復過程。
    注意:對於單線程的從庫(slave_parallel_workers設置爲0),在沒有任何其他意外發生的情況下,複製通道無需進一步設置即可成功恢復複製。
    對於多線程的從庫(slave_parallel_workers大於0),中繼日誌恢復可能會失敗,因爲它通常不能自動完成。在這種情況下,會發出一條錯誤消息,您必須手動設置通道

5.1利用遠程克隆數據,部署基於gtid主從複製搭建

在mysql8.0上是不支持如下的授權方式:

192.168.1.105 master庫操作:
錯誤的授權姿勢

root@localhost [test001]>grant replication slave on *.* to novelrep@'192.168.1.182' identified by 'JuwoSdk21TbUser'; flush privileges;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by 'JuwoSdk21TbUser'' at line 1
Query OK, 0 rows affected (0.02 sec)

正確的授權姿勢

root@localhost [test001]>create user novelrep@'192.168.1.182' identified by 'JuwoSdk21TbUser'; grant replication slave on *.* to novelrep@'192.168.1.182';
Query OK, 0 rows affected (0.03 sec)

Query OK, 0 rows affected (0.00 sec)
CHANGE MASTER TO MASTER_HOST='192.168.1.105',MASTER_PORT=3306,MASTER_USER='novelrep',MASTER_PASSWORD='JuwoSdk21TbUser',MASTER_AUTO_POSITION = 1;start slave;
報錯:
Last_IO_Errno: 2061
            Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 60 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.

解決辦法:

    root@localhost [(none)]>create user novelrep@'192.168.1.182' identified WITH 'mysql_native_password' by 'JuwoSdk21TbUser'; grant replication slave on *.* to novelrep@'192.168.1.182';
Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.00 sec)

192.168.1.182庫操作:

    CHANGE MASTER TO MASTER_HOST='192.168.1.105',MASTER_PORT=3306,MASTER_USER='novelrep',MASTER_PASSWORD='JuwoSdk21TbUser',MASTER_AUTO_POSITION = 1;start slave;        
  Last_IO_Errno: 13117
                Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

原因是server_id衝突了

解決辦法:修改192.168.1.182上的server-id
show slave status\G 自動恢復複製,複製正常

六、克隆插件回顧總結

6.1本地clone+還原注意事項:

5.1只克隆innodb存儲引擎的數據。非INNODB引擎的表只會生成空表。
5.2 不會克隆原實例的全部目錄結構,只克隆了data目錄下的相關數據。
5.3 克隆的目標目錄必須不存在,克隆過程會生成該目錄,所以原實例的啓動賬戶要有創建目錄的權限。
5.4 克隆後的目錄會自動設置:mysql:mysql
5.5 克隆目標目錄不會生成原實例自定義的innodb_undo_directory
5.6 克隆不會拷貝原實例的binlog文件

6.2遠程克隆數據注意事項:

執行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。

6.3.其他注意事項

克隆操作期間不允許DDL(包括TRUNCATE TABLE)。
一次只能克隆一個MySQL實例。不支持在單個克隆操作中克隆多個MySQL實例。
遠程克隆操作(在CLONE INSTANCE語句中指定Donor的MySQL服務器實例的端口號時)不支持mysqlx_port指定的X協議端口。
clone插件不支持MySQL配置參數的克隆。
clone插件不支持二進制日誌的克隆。
克隆插件僅克隆存儲在InnoDB中的數據。其他存儲引擎數據未克隆。存儲在任何數據庫(包括sys模式)中的MyISAM和CSV表都被克隆爲空表

鳴謝:本博文是在學些了馬蜂窩高級DBA張充和愛可生高級DBA羅小波分享在知書堂微信公衆號的關於MySQL8.0的clone plugin插件的文章。結合自己的理解總結於此。特別感謝二位的分享。同時我也分享出來,希望能幫助到更多的愛好MySQL夥伴,一起交流,一起成長。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章