Clone Plugin是MySQL 8.0.17引入的一個重大特性。有了Clone Plugin,我們可以很友善的進行備份恢複,添加slave,及MGR節點擴充。
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支援以下兩種安裝方式:
(1)配置檔案指定
這裡的clone,嚴格來說,不是參數名,而是插件名,可加可不加,FORCE_PLUS_PERMANENT 控制插件的行為。
有四個取值:
ON(開啟插件)
OFF(禁用插件),
FORCE(強制開啟。如果插件初始化失敗,MySQL将不會啟動)
FORCE_PLUS_PERMANENT(在FORCE的基礎上,不允許通過UNINSTALL PLUGIN指令解除安裝插件)。
(2)動态加載
檢視插件是否安裝成功
clone狀态顯示為”ACTIVE“代表插件加載成功。
Clone Plugin支援兩種克隆方式:本地克隆和遠端克隆。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CN3EzN4ITNmVWOwY2N4QGMkNmZmFGNhJmMklTYiV2Y5MDOx0Cc19CX0VmbjN3bvwFdl5mLh5WaoN2cv5yZtl2Yz92Lc9CX6MHc0RHaiojIsJye.png)
本地克隆是在執行個體本地發起的,其文法如下:
其中,clone_dir是克隆目錄。
下面看個具體的Demo。
建立克隆使用者
建立克隆目錄
建立本地克隆
其中,“/data/mysql/3307” 是克隆目錄,其需滿足以下幾點要求:
克隆目錄必須是絕對路徑。 “/data/mysql”必須存在,且MySQL對其有可寫權限。 3307不能存在。
檢視克隆目錄的内容
相對于Xtrabackup,無需Prepare,直接即可啟動使用。
遠端克隆涉及兩個執行個體,其中,待克隆的執行個體是Donor,接受克隆資料的執行個體是Recipient。克隆指令需在Recipient上發起,文法如下:
其中,host,port 是待克隆執行個體的(Donor)的IP和端口,user,password是Donor上的克隆使用者和密碼,需要backup_admin權限,如上面建立的clone_user。
DATA DIRECTORY指定備份目錄,不指定的話,則預設克隆到Recipient的資料目錄下。
REQUIRE [NO] SSL,是否開啟SSL通信。
下面,看個具體Demo。
首先,在Donor執行個體上建立克隆使用者,加載Clone Plugin。
backup_admin是克隆操作必需權限。
接着,在Recipient執行個體上建立克隆使用者,加載Clone Plugin。
這裡的clone_admin,隐式含有backup_admin(阻塞DDL)和shutdown(重新開機執行個體)權限。
設定Donor白名單。Recipient隻能克隆白名單中的執行個體。
設定該參數需要SYSTEM_VARIABLES_ADMIN權限。
在Recipient上發起克隆指令
遠端克隆會依次進行以下操作:
(1)擷取備份鎖。備份鎖和DDL互斥。注意,不僅僅是Recipient,Donor上的備份鎖同樣會擷取。
(2)DROP使用者表空間。注意,DROP的隻是使用者資料,不是資料目錄,也不包括mysql,ibdata等系統表空間。
(3)從Donor執行個體拷貝資料。對于使用者表空間,會直接拷貝,如果是系統表空間 ,則會重命名為xxx.#clone,不會直接替代原檔案。
(4)重新開機執行個體。在啟動的過程中,會用xxx.#clone替換掉原來的系統表空間檔案。
檢視克隆操作的進度主要依托于performance_schema.clone_status和performance_schema.clone_progress這兩張表。
首先看看performance_schema.clone_status表。
顧名思義,該表記錄了克隆操作的目前狀态。
其中,
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表。
該表記錄了克隆操作的進度資訊。
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執行個體的一緻性位置點資訊。我們可以利用這些資訊來搭建從庫。
這裡,區分兩種場景,GTID複制和基于位置點的複制。
需要注意的是,無需額外執行set global gtid_purged操作。通過克隆資料啟動的執行個體,gtid_purged已經初始化完畢。
這裡,同樣要區分兩種場景。
場景1,Recipient要作為Donor的從庫。
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主庫的從庫。
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個階段。
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端口。
除此之外,在進行遠端克隆時,還會進行如下檢查:
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必須一緻。
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_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:
https://dev.mysql.com/worklog/task/?id=9209
InnoDB: Clone remote replica:
https://dev.mysql.com/worklog/task/?id=9210
InnoDB: Clone Replication Coordinates
https://dev.mysql.com/worklog/task/?id=9211
InnoDB: Clone Remote provisioning:
https://dev.mysql.com/worklog/task/?id=11636
MySQL/InnoDB資料克隆插件(clone plugin)實作剖析
https://zhuanlan.zhihu.com/p/79328512
作者:Chen Chen
分享 vivo 網際網路技術幹貨與沙龍活動,推薦最新行業動态與熱門會議。