MySQL 8 新特性之Clone Plugin
Clone Plugin是MySQL 8.0.17引入的一個重大特性,為什麼要實現這個特性呢?個人感覺,主要還是為Group Replication服務。在Group Replication中,新增一個新的節點,差異資料的補齊是透過分散式恢復(Distributed Recovery)來實現的。
在MySQL 8.0.17之前,只支援一種恢復方式-Binlog。但如果新節點需要的Binlog已經被Purge了,這個時候,只能先借助於備份工具(XtraBackup,mydumper,mysqldump)做個全量資料的同步,然後再透過分散式恢復同步增量資料。
這種方式,雖然也能實現新增節點的目的,但總歸還是要藉助於外部工具,需要一定的工作量和使用門檻。要知道,其競爭對手,PXC,預設整合了XtraBackup進行State Snapshot Transfer(類似於全量同步),而MongoDB則更進一步,原生就實現了Initial Sync同步全量資料。從易用性來看,單就叢集新增節點這一項而言,MySQL確實不如其競爭對手。客戶體驗上,還有很大的提升空間。
好在MySQL官方也正視到這個差距,終於在MySQL 8.0.17實現了Clone Plugin。當然,對於官方來說,實現這個特性並不算難,畢竟有現成的物理備份工具(MySQL Enterprise Backup)可供借鑑。
本文將從以下幾個方面展開:
- Clone Plugin的安裝
- Clone Plugin的使用
- 如何檢視克隆操作的進度
- 如何基於克隆資料搭建從庫
- Clone Plugin的實現細節
- Clone Plugin的限制
- Clone Plugin與XtraBackup的對比
- Clone Plugin的引數解析
一、Clone Plugin的安裝
Clone Plugin支援以下兩種安裝方式:
(1)配置檔案指定
1
2
3 |
[mysqld] plugin-
load
-
add
=mysql_clone.so clone=FORCE_PLUS_PERMANENT |
這裡的clone,嚴格來說,不是引數名,而是外掛名,可加可不加,FORCE_PLUS_PERMANENT 控制外掛的行為。
有四個取值:
- ON (開啟外掛)
- OFF(禁用外掛),
- FORCE(強制開啟。如果外掛初始化失敗,MySQL將不會啟動)
- FORCE_PLUS_PERMANENT(在FORCE的基礎上,不允許透過UNINSTALL PLUGIN命令解除安裝外掛)。
(2)動態載入
1
2
3 |
[mysqld] plugin-
load
-
add
=mysql_clone.so clone=FORCE_PLUS_PERMANENT |
檢視外掛是否安裝成功
1
2
3
4 |
mysql> show plugins; ... | clone | ACTIVE | CLONE | mysql_clone.so | GPL | ... |
clone狀態顯示為”ACTIVE“代表外掛載入成功。
二、Clone Plugin的使用
Clone Plugin支援兩種克隆方式:本地克隆和遠端克隆。
1、 本地克隆
本地克隆是在例項本地發起的,其語法如下:
1 |
CLONE
LOCAL
DATA DIRECTORY [=]
'clone_dir'
; |
其中,clone_dir是克隆目錄。
下面看個具體的Demo。
建立克隆使用者
1
2 |
mysql>
create
user
'clone_user'
@
'%'
identified
by
'clone_pass'
; mysql>
grant
backup_admin
on
*.*
to
'clone_user'
@
'%'
; |
建立克隆目錄
1
2 |
# mkdir /data/mysql # chown -R mysql.mysql /data/mysql |
建立本地克隆
1
2 |
# mysql -uclone_user -pclone_pass mysql> clone
local
data directory=
'/data/mysql/3307'
; |
其中,“/data/mysql/3307” 是克隆目錄,其需滿足以下幾點要求:
- 克隆目錄必須是絕對路徑。
- “/data/mysql”必須存在,且MySQL對其有可寫許可權。
- 3307不能存在。
檢視克隆目錄的內容
1
2
3
4
5
6
7
8
9
10
11
12
13 |
# 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,無需Prepare,直接即可啟動使用。
1 |
# /usr/
local
/mysql/bin/mysqld
--no-defaults --datadir=/data/mysql/3307 --user mysql --port 3307 & |
2、遠端克隆
遠端克隆涉及兩個例項,其中,待克隆的例項是Donor,接受克隆資料的例項是Recipient。克隆命令需在Recipient上發起,語法如下:
1
2
3
4 |
CLONE INSTANCE
FROM
'user'
@
'host'
:port IDENTIFIED
BY
'password' [DATA DIRECTORY [=]
'clone_dir'
] [REQUIRE [
NO
] SSL]; |
其中,host,port 是待克隆例項的(Donor)的IP和埠,user,password是Donor上的克隆使用者和密碼,需要backup_admin許可權,如上面建立的clone_user。
DATA DIRECTORY指定備份目錄,不指定的話,則預設克隆到Recipient的資料目錄下。
REQUIRE [NO] SSL,是否開啟SSL通訊。
下面,看個具體Demo。
首先,在Donor例項上建立克隆使用者,載入Clone Plugin。
1
2
3 |
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是克隆操作必需許可權。
接著,在Recipient例項上建立克隆使用者,載入Clone Plugin。
1
2
3 |
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只能克隆白名單中的例項。
1 |
mysql>
set
global
clone_valid_donor_list =
'192.168.244.10:3306'
; |
設定該引數需要SYSTEM_VARIABLES_ADMIN許可權。
在Recipient上發起克隆命令
1
2
3 |
# 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,不會直接替代原檔案。
1
2
3
4
5
6
7
8
9
10
11
12 |
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表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
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表。
1
2
3
4
5
6
7
8
9
10
11
12
13 |
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例項的一致性位置點資訊。我們可以利用這些資訊來搭建從庫。
1
2
3
4
5
6
7 |
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複製和基於位置點的複製。
1、GTID複製
1
2
3
4 |
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已經初始化完畢。
1
2
3
4
5
6
7 |
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) |
2、基於位置點的複製
這裡,同樣要區分兩種場景。
場景1,Recipient要作為Donor的從庫。
1
2
3
4
5
6 |
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主庫的從庫。
1
2
3
4
5
6 |
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中的資訊自動建立複製,很多時候,這未必是我們的預期行為。
五、Clone Plugin的實現細節
克隆操作可細分為以下5個階段。
1 |
[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()銷燬克隆物件。
六、Clone Plugin的限制
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埠。
除此之外,在進行遠端克隆時,還會進行如下檢查:
- MySQL版本(包括小版本)必須一致,且支援Clone Plugin。
- 主機的作業系統和位數(32位,64位)必須一致。兩者可根據version_compile_os,version_compile_machine引數獲取。
- Recipient必須有足夠的磁碟空間儲存克隆資料。
- 字符集(character_set_server),校驗集(collation_server),character_set_filesystem必須一致。
- innodb_page_size必須一致。會檢查innodb_data_file_path中ibdata的數量和大小。
- 目前Clone Plugin(8.0.20)的實現,無論是Donor,還是Recipient,同一時間,只能執行一個克隆操作。後續會支援多個克隆操作併發執行。
- Recipient需要重啟,所以其必須透過mysqld_safe或systemd等進行管理。如果是透過mysqld進行啟動,例項關閉後,需要手動啟動。
- ACTIVE狀態的Plugin必須一致。
七、Clone Plugin與XtraBackup的對比
1、在實現上,兩者都有FILE COPY和REDO COPY階段,但Clone Plugin比XtraBackup多了一個PAGE COPY,由此帶來的好處是,Clone Plugin的恢復速度比XtraBackup更快。
2、XtraBackup沒有Redo Archiving特性,有可能出現未複製的Redo日誌被覆蓋的情況。
3、GTID下建立複製,無需額外執行set global gtid_purged操作。
八、Clone Plugin的引數解析
- clone_autotune_concurrency 是否自動調節克隆過程中併發執行緒數的數量,預設為ON,此時,最大執行緒數受clone_max_concurrency引數控制。若設定為OFF,則併發執行緒數的數量將是固定的,同clone_max_concurrency引數一致。該引數的預設值為16。
- clone_buffer_size 本地克隆時,中轉緩衝區的大小,預設4M。緩衝區越大,備份速度越快,相應的,對磁碟IO的壓力越大。
- clone_ddl_timeout 克隆操作需要獲取備份鎖(Backup Lock)。如果在執行CLONE命令時,有DDL在執行,則CLONE命令會被阻塞,等待獲取備份鎖(Waiting for backup lock)。等待的最大時長由clone_ddl_timeout引數決定,預設300(單位秒)。如果在這個時間內還沒獲取到鎖,CLONE命令會失敗,且提示“ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction”。
需要注意的是,如果在執行DDL時,有CLONE命令在執行,DDL同樣會因獲取不到備份鎖被阻塞,只不過,DDL操作的等待時長由lock_wait_timeout引數決定,該引數的預設值為31536000s,即365天。
- clone_enable_compression 遠端克隆,在傳輸資料時,是否開啟壓縮。開啟壓縮能節省網路頻寬,但相應的,會增加CPU消耗。
- clone_max_data_bandwidth 遠端克隆時,可允許的最大資料複製速率(單位MiB/s)。預設為0,不限制。注意,這裡限制的只是單個執行緒的複製速率,如果存在多個執行緒並行複製,實際最大複製速率=clone_max_data_bandwidth*執行緒數。
- clone_max_network_bandwidth 遠端克隆時,可允許的最大網路傳輸速率(單位MiB/s)。預設為0,不限制。如果網路頻寬存在瓶頸,可透過該引數進行限速。
- clone_valid_donor_list 設定Donor白名單,只能克隆白名單中指定的例項。
- clone_ssl_ca,clone_ssl_cert,clone_ssl_key SSL相關。
九、參考資料
-
InnoDB: Clone local replica:
-
InnoDB: Clone remote replica:
-
InnoDB: Clone Replication Coordinates
-
InnoDB: Clone Remote provisioning:
-
MySQL/InnoDB資料克隆外掛(clone plugin)實現剖析
作者:Chen Chen
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69912579/viewspace-2730737/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL 8 新特性之Invisible IndexesMySqlIndex
- MySQL 8 新特性之自增主鍵的持久化MySql持久化
- MySQL-18 MySQL8其他新特性MySql
- 【MySQL】5.7新特性之四MySql
- 【MySQL】5.7新特性之五MySql
- 【MySQL】5.7新特性之六MySql
- 【MySQL】5.7新特性之七MySql
- JDK8新特性之stream()JDK
- Java8新特性之:OptionalJava
- Java 8 新特性之方法引用Java
- MySQL 8 新特性之持久化全域性變數的修改MySql持久化變數
- MySQL 8部分新特性(8.0.17)MySql
- ?Java8新特性之Optional類Java
- java8 新特性之方法引用Java
- java8 新特性之Optional 類Java
- Java8 新特性之 Optional 類Java
- JDK8新特性之Stream流JDK
- 【MySQL】MySQL5.6新特性之Batched Key AccessMySqlBAT
- 【MySQL】MySQL5.6新特性之crash-safeMySql
- PHP8新特性之match表示式PHP
- java8 新特性之Lambda 表示式Java
- java8 新特性之預設方法Java
- Java8新特性探索之Stream介面Java
- Java8 新特性之 Lambda 表示式Java
- Java8新特性之時間APIJavaAPI
- Java 8 新特性Java
- Java 8 新特性Java
- Java 8新特性Java
- 【Mysql】Mysql5.7新特性之-json儲存MySqlJSON
- 【Mysql】mysql5.7新特性之-sys schema的作用MySql
- 【Mysql】MySQL 5.7新特性之Generated Column(函式索引)MySql函式索引
- MySQL8 非常有用的一個新特性MySql
- java8 新特性之函式式介面Java函式
- java8新特性之lambda表示式(一)Java
- Java8 新特性之預設介面方法Java
- java8 之 Java官方庫的新特性Java
- JDK8新特性之函式式介面JDK函式
- #MySQL# mysql5.7新特性之半同步複製MySql