技術分享 | 實戰 MySQL 8.0.17 Clone Plugin
原創: 陳俊聰
背景
很神奇,5.7.17 和 8.0.17,連續兩個17小版本都讓人眼前一亮。前者加入了組複製(Group Replication)功能,後者加入了克隆外掛(Clone Plugin)功能。今天我們實戰測試一下這個新功能。
克隆外掛簡介
克隆外掛允許在本地或從遠端 MySQL 例項克隆資料。克隆資料是儲存在 InnoDB 其中的資料的物理快照,其中包括庫、表、表空間和資料字典元資料。克隆的資料包含一個功能齊全的資料目錄,允許使用克隆外掛進行 MySQL 伺服器配置。
克隆外掛支援兩種克隆方式
-
本地克隆
-
遠端克隆
本地克隆
本地克隆操作將啟動克隆操作的 MySQL 伺服器例項中的資料克隆到同伺服器或同節點上的一個目錄裡
遠端克隆
預設情況下,遠端克隆操作會刪除接受者(recipient)資料目錄中的資料,並將其替換為捐贈者(donor)的克隆資料。(可選)您也可以將資料克隆到接受者的其他目錄,以避免刪除現有資料。
遠端克隆操作和本地克隆操作克隆的資料沒有區別,資料是相同的。
克隆外掛支援複製。除克隆資料外,克隆操作還從捐贈者中提取並傳輸複製位置資訊,並將其應用於接受者,從而可以使用克隆外掛來配置組複製或主從複製。使用克隆外掛進行配置比複製大量事務要快得多,效率更高。
實戰部分
一、本地克隆
安裝克隆外掛
啟動前
[mysqld]
plugin-load-add=mysql_clone.so
或執行中
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
| 第二種方法會註冊到元資料,所以不用擔心重啟外掛會失效。兩種方法都很好用
檢查外掛有沒有啟用
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'clone'; +-------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +-------------+---------------+ | clone | ACTIVE | +-------------+---------------+ 1 row in set (0.01 sec)
設定強制啟動失敗引數
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT
| 如果克隆外掛對你們很重要,可以設定clone=FORCE_PLUS_PERMANENT或clone=FORCE。作用是:如果外掛未成功初始化,就會強制mysqld啟動失敗。
克隆需要的許可權
需要有備份鎖的許可權。備份鎖是 MySQL 8.0 的新特性之一,比5.7版本的flush table with read lock要輕量。
mysql> CREATE USER clone_user@'%' IDENTIFIED by 'password';
mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user'; # BACKUP_ADMIN是MySQL8.0 才有的備份鎖的許可權
執行本地克隆
mysql -uclone_user -ppassword -S /tmp/mysql3008.sock
mysql> CLONE LOCAL DATA DIRECTORY = '/fander/clone_dir';
| 例子中需要 MySQL 的執行使用者擁有 fander 目錄的rwx許可權,要求 clone_dir 目錄不存在
本地克隆的步驟如下
-
DROP DATA
-
FILE COPY
-
PAGE COPY
-
REDO COPY
-
FILE SYNC
觀察方法如下
mysql> SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress;
+-----------+-------------+----------------------------+
| STAGE | STATE | END_TIME |
+-----------+-------------+----------------------------+
| DROP DATA | Completed | 2019-07-25 21:00:18.858471 |
| FILE COPY | Completed | 2019-07-25 21:00:19.071174 |
| PAGE COPY | Completed | 2019-07-25 21:00:19.075325 |
| REDO COPY | Completed | 2019-07-25 21:00:19.076661 |
| FILE SYNC | Completed | 2019-07-25 21:00:19.168961 |
| RESTART | Not Started | NULL |
| RECOVERY | Not Started | NULL |
+-----------+-------------+----------------------------+
7 rows in set (0.00 sec)
當然還有另外一個觀察方法
mysql> set global log_error_verbosity=3;
Query OK, 0 rows affected (0.00 sec)
mysql> CLONE LOCAL DATA DIRECTORY = '/fander/clone6_dir';
Query OK, 0 rows affected (0.24 sec)
[root@192-168-199-101 data]# tailf mysql-error.err
2019-07-25T22:22:58.261861+08:00 8 [Note] [MY-013457] [InnoDB] Clone Begin Master Task by root@localhost
2019-07-25T22:22:58.262422+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply Master Loop Back
2019-07-25T22:22:58.262523+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply Begin Master Task
...
2019-07-25T22:22:58.471108+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State FLUSH DATA:
2019-07-25T22:22:58.472178+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State FLUSH REDO:
2019-07-25T22:22:58.506488+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State DONE
2019-07-25T22:22:58.506676+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply End Master Task ID: 0 Passed, code: 0:
2019-07-25T22:22:58.506707+08:00 8 [Note] [MY-013457] [InnoDB] Clone End Master Task ID: 0 Passed, code: 0:
測試,起一個克隆的例項
/opt/mysql8.0/bin/mysqld --datadir=/fander/clone_dir --port=3333 --socket=/tmp/mysql3333.sock --user=mysql3008user --lower-case-table-names=1 --mysqlx=OFF
#解釋,因為我沒有使用my.cnf,所以加了比較多引數
#--datadir 指定啟動的資料目錄
#--port 指定啟動的MySQL監聽埠
#--socket 指定socket路徑
#--user `捐贈者`的目錄許可權是mysql3008user:mysql3008user,使用者也是mysql3008user,我沒有修改
#--lower-case-table-names=1 同`捐贈者`
#--mysqlx=OFF 不關閉的話,預設mysqlx埠會合`捐贈者`的33060重複衝突
#登入檢查
mysql -uroot -proot -S /tmp/mysql3333.sock
mysql> show master status\G # 可見GTID是`捐贈者`的子集,所以說明`接受者`直接和`捐贈者`建主從複製是很簡單的
二、遠端克隆
遠端克隆的前提條件和限制
-
捐贈者和接受者都需要安裝克隆外掛
-
捐贈者和接受者分別需要有至少BACKUP_ADMIN/CLONE_ADMIN許可權的賬號
| 暗示了接受者必須先啟動一個數據庫例項(空或有資料的例項均可,因為都會被刪除)
-
克隆目標目錄必須有寫入許可權
-
克隆操作期間不允許使用 DDL,允許併發DML。要求相同版本號,您無法MySQL 5.7和MySQL 8.0之間進行克隆,而且要求版本>=8.0.17
-
同一平臺同一架構,例如linux to windows、x64 to x32 是不支援。
-
足夠的磁碟空間
-
可以克隆操作一般表空間,但必須要有目錄許可權,不支援克隆使用絕對路徑建立的一般空間。與源表空間檔案具有相同路徑的克隆表空間檔案將導致衝突
-
遠端克隆時不支援CLONE INSTANCE FROM中通過使用mysqlx的埠
-
克隆外掛不支援克隆MySQL伺服器配置my.cnf等
-
克隆外掛不支援克隆二進位制日誌。
-
克隆外掛僅克隆儲存的資料 InnoDB。不克隆其他儲存引擎資料。MyISAM並且 CSV儲存在包括sys模式的任何模式中的表都被克隆為空表。
-
不支援通過MySQL router連線到捐贈者例項。
-
一些引數是必須一致的,例如innodb_page_size、innodb_data_file_path、--lower_case_table_ names
-
如果克隆加密或頁面壓縮資料,則捐贈者和接收者必須具有相同的檔案系統塊大小
-
如果要克隆加密資料,則需要安全連線
-
clone_valid_donor_list 在接受者的設定必須包含捐贈者 MySQL 伺服器例項的主機地址。
-
必須沒有其他克隆操作正在執行。一次只允許一次克隆操作。要確定克隆操作是否正在執行,請查詢該 clone_status表。
-
預設情況下,克隆資料後會自動重新啟動接受者 MySQL 例項。要自動重新啟動,必須在接收方上提供監視程序以檢測伺服器是否已關閉。否則,在克隆資料後,克隆操作將停止並出現以下錯誤,並且關閉接受者 MySQL 伺服器例項:
| 此錯誤不表示克隆失敗。這意味著必須在克隆資料後手動重新啟動接受者的 MySQL 例項。
遠端克隆實戰
假設前提條件都滿足,步驟如下
和本地克隆一樣,遠端克隆需要外掛安裝和使用者授權。捐贈者、接受者的授權略有不同。
1. 確保捐贈者和接受者都安裝了克隆外掛
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
2. 使用者賬號授權
捐贈者授權
mysql> CREATE USER clone_user@'192.168.199.101' IDENTIFIED by 'password1';
mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user'@'192.168.199.101'; # BACKUP_ADMIN是MySQL8.0 才有的備份鎖的許可權
接受者授權
mysql> CREATE USER clone_user@'192.168.199.102' IDENTIFIED by 'password2';
mysql> GRANT CLONE_ADMIN ON *.* TO 'clone_user'@'192.168.199.102';
| CLONE_ADMIN許可權 = BACKUP_ADMIN許可權 + SHUTDOWN許可權。SHUTDOWN僅限允許使用者shutdown和restart mysqld。授權不同是因為,接受者需要restart mysqld。
3. 接受者設定捐贈者列表清單
mysql -uclone_user -ppassword2 -h192.168.199.102 -P3008
mysql> SET GLOBAL clone_valid_donor_list = '192.168.199.101:3008';
| 這看起來是一個安全相關引數。多個例項用逗號分隔,例如“HOST1:PORT1,HOST2:PORT2,HOST3:PORT3”
接受者開始拉取克隆捐贈者資料
CLONE INSTANCE FROM clone_user@'192.168.199.101':3008
IDENTIFIED BY 'password1';
遠端克隆步驟如下
mysql> SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress;
+-----------+-----------+----------------------------+
| STAGE | STATE | END_TIME |
+-----------+-----------+----------------------------+
| DROP DATA | Completed | 2019-07-25 21:56:01.725783 |
| FILE COPY | Completed | 2019-07-25 21:56:02.228686 |
| PAGE COPY | Completed | 2019-07-25 21:56:02.331409 |
| REDO COPY | Completed | 2019-07-25 21:56:02.432468 |
| FILE SYNC | Completed | 2019-07-25 21:56:02.576936 |
| RESTART | Completed | 2019-07-25 21:56:06.564090 |
| RECOVERY | Completed | 2019-07-25 21:56:06.892049 |
+-----------+-----------+----------------------------+
7 rows in set (0.01 sec)
接受者如果非mysqld_safe啟動的,會報錯誤,但不影響克隆,需要您人手啟動mysqld即可。
ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process).
實操後小結:克隆與xtrabackup的對比
-
克隆和xtrabackup備份都屬於物理熱備,備份恢復原理也近似。
-
克隆在恢復例項時需要先啟動一個例項並授權,而xtrabackup不需要。
-
xtrabackup在backup後需要apply log,克隆是類似mysqlbackup提供的backup-and-apply-log,合併在一起做。
-
xtrabackup備份檔案的許可權等於執行命令的人的許可權,恢復例項時需要人手chown回例項許可權,克隆備份後許可權和原資料許可權一致,無需再人手chown,方便恢復。
-
xtrabackup恢復時需要在mysql中執行reset master;然後set global gtid_purged="UUID:NUMBER",具體的UUID:NUMBER的值為備份檔案中的xtrabackup_info檔案的內容;克隆不需要這個操作步驟,預設克隆完就可以建立複製了。
-
xtrabackup備份完一般是scp拷貝到另外一臺機器恢復,走的是22埠;克隆走的是MySQL的監聽埠。所以在目錄許可權正確的情況下,甚至根本不需要登入Linux伺服器的許可權。如下:
[root@192-168-199-103 ~]# mysql -uroot -ppassword2 -h192.168.199.102 -P3008 -e "SET GLOBAL clone_valid_donor_list = '192.168.199.101:3008';"
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@192-168-199-103 ~]# mysql -uroot -ppassword2 -h192.168.199.102 -P3008 -e "CLONE INSTANCE FROM root@'192.168.199.101':3008 IDENTIFIED BY 'password1';"
mysql: [Warning] Using a password on the command line interface can be insecure.
三、利用克隆建立主從複製
克隆出來的接受者例項,可以與捐贈者建立主從複製。當然建立組複製也是可以的,鑑於篇幅的原因,不做示例有興趣可以閱讀官方文件18.4.3.1節“克隆分散式恢復”。
| https://dev.mysql.com/doc/refman/8.0/en/group-replication-cloning.html
傳統複製時,通過以下命令檢視postion位置
mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
+------------------+-----------------+
| BINLOG_FILE | BINLOG_POSITION |
+------------------+-----------------+
| mysql-bin.000014 | 2179 |
+------------------+-----------------+
1 row in set (0.01 sec)
GTID複製時,通過以下命令檢視GTID位置
mysql> SELECT @@GLOBAL.GTID_EXECUTED;
+-------------------------------------------+
| @@GLOBAL.GTID_EXECUTED |
+-------------------------------------------+
| 990fa9a4-7aca-11e9-89fa-000c29abbade:1-11 |
+-------------------------------------------+
1 row in set (0.00 sec)
假設已經有如下授權,我們就可以建立複製啦
create user repl@'%' identified WITH 'mysql_native_password' by 'password';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'%';
建立GTID主從複製關係
(接受者上)
-
CHANGE MASTER TO MASTER_HOST='192.168.199.101', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_PORT=3008, MASTER_AUTO_POSITION=1;
監控克隆操作
檢查克隆進度
mysql> SELECT STATE FROM performance_schema.clone_status;
+-----------+
| STATE |
+-----------+
| Completed |
+-----------+
1 row in set (0.00 sec)
SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;
檢查克隆是否出錯
mysql> SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;
+-----------+----------+---------------+
| STATE | ERROR_NO | ERROR_MESSAGE |
+-----------+----------+---------------+
| Completed | 0 | |
+-----------+----------+---------------+
1 row in set (0.00 sec)
檢查克隆次數
show global status like 'Com_clone'; # `捐贈者` 每次+1,`接受者` 0
隨時可以kill掉克隆
使用
SELECT * FROM performance_schema.clone_status\G
或
show processlist
檢視執行緒ID,然後kill ID
總結
克隆功能非常有趣。他操作簡單,可以用於快速搭建、恢復主從複製或組複製,可以部分取代開源熱備軟體xtrabackup,期待未來官方會把他做得越來越好,功