root@localhost : (none):45: > SELECT * FROM performance_schema.replication_group_members;
+--+---+---+---+----+---+-+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+--+---+---+---+----+---+-+
| group_replication_applier | 2d283e92-de7b-11e9-a14d-525400c33752 | node2 | 3306 | ONLINE | SECONDARY | 8.0.17 |
| group_replication_applier | 2e33b2a7-de7b-11e9-9a21-525400bdd1f2 | node3 | 3306 | ONLINE | SECONDARY | 8.0.17 |
| group_replication_applier | 320675e6-de7b-11e9-b3a9-5254002a54f2 | node1 | 3306 | ONLINE | PRIMARY | 8.0.17 |
+--+---+---+---+----+---+-+
3 rows in set (0.00 sec)
# 在node3中執行備份命令
[root@node3 ~]# xtrabackup --defaults-file=/etc/my.cnf --user=admin --password='letsg0' --backup --target-dir=/data//backup/
.
191012 17:19:37 Backup created in directory '/data/backup/'
MySQL binlog position: filename 'mysql-bin.000023', position '231', GTID of the last change '320675e6-de7b-11e9-b3a9-5254002a54f2:1-4,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2771494'
191012 17:19:37 [00] Writing /data/backup/backup-my.cnf
191012 17:19:37 [00] ...done
191012 17:19:37 [00] Writing /data/backup/xtrabackup_info
191012 17:19:37 [00] ...done
xtrabackup: Transaction log of lsn (11495841139) to (11495843979) was copied.
191012 17:19:37 completed OK!
# 備份完成之後查看備份數據目錄中的數據文件
[root@node3 ~]# ll /data//backup/
total 2147376
-rw-r 1 root root 515 Oct 12 17:19 backup-my.cnf
-rw-r 1 root root 2147483648 Oct 12 17:19 ibdata1
drwxr-x--- 2 root root 143 Oct 12 17:19 mysql
-rw-r 1 root root 231 Oct 12 17:19 mysql-bin.000023
-rw-r 1 root root 52 Oct 12 17:19 mysql-bin.index
-rw-r 1 root root 24117248 Oct 12 17:19 mysql.ibd
drwxr-x--- 2 root root 8192 Oct 12 17:19 performance_schema
drwxr-x--- 2 root root 44 Oct 12 17:19 sbtest
drwxr-x--- 2 root root 28 Oct 12 17:19 sys
drwxr-x--- 2 root root 20 Oct 12 17:19 test
-rw-r 1 root root 13631488 Oct 12 17:19 undo_001
-rw-r 1 root root 13631488 Oct 12 17:19 undo_002
-rw-r 1 root root 109 Oct 12 17:19 xtrabackup_binlog_info
-rw-r 1 root root 101 Oct 12 17:19 xtrabackup_checkpoints
-rw-r 1 root root 622 Oct 12 17:19 xtrabackup_info
-rw-r 1 root root 5632 Oct 12 17:19 xtrabackup_logfile
-rw-r 1 root root 262 Oct 12 17:19 xtrabackup_tablespaces
# 在這個例子中,我們假設主機都是Linux伺服器,並使用SCP在它們之間複製文件
## 在node4中創建用於存放備份數據的目錄
[root@node4 ~]# mkdir /data/backup/xtrabackup_dir
## 在node3中將備份數據使用SCP傳送到node4中
[root@node3 ~]# scp -r /data//backup/ 10.10.30.16:/data/backup/xtrabackup_dir
# 首先停止目標伺服器的資料庫進程
[root@physical-machine ~]# service mysqld stop
Shutting down MySQL SUCCESS!
[root@physical-machine ~]# ps aux |grep mysqld |grep -v grep
[root@physical-machine ~]#
# 注意:如果是用備份數據來恢復發生故障的成員,且故障成員的主機未宕機,則建議將故障成員的datadir下的auto.cnf和mysqld-auto.cnf文件先拷貝出來,稍後使用備份數據恢復完成之後,再拷貝回原目錄(auto.cnf中記錄著源實例的UUID,使用該UUID來對實例進行恢復時,可確保故障實例可以以原來的身份重新加入組,而不是重新生成一個UUID以新的身份加入組;mysqld-auto.cnf記錄了Server本地的一些系統變量的臨時持久化設置),拷貝命令類似如下
[root@node2 ~]# cp -ar /data//mysqldata1/mydata/{auto.cnf,mysqld-auto.cnf} /data/backup/
[root@node2 ~]# ll /data//backup/*.cnf
-rw-r 1 mysql mysql 56 Sep 24 11:27 /data//backup/auto.cnf
-rw-r 1 mysql mysql 414 Sep 25 17:12 /data//backup/mysqld-auto.cnf
# 必須清空共享表空間(innodb_data_home_dir)、獨立表空間(datadir)、獨立undo表空間(innodb_undo_directory)、redo log日誌(innodb_log_group_home_dir)數據文件所在的目錄,否則後續恢復將無法拷貝文件(如果可以,中繼日誌、二進位日誌所在的目錄也一併清空),類似如下
[root@node4 ~]# rm -rf /data/mysqldata1/{binlog,innodb_log,innodb_ts,mydata,relaylog,undo}/*
# 執行恢復語句
[root@node4 ~]# xtrabackup --prepare --target-dir=/data/backup/xtrabackup_dir/backup/
.
FTS optimize thread exiting.
Starting shutdown...
Log background threads are being closed...
Shutdown completed; log sequence number 11495844364
191014 15:32:39 completed OK!
# 執行完成恢復之後,查看備份數據文件所在目錄,可以發現多了一些文件和目錄
[root@physical-machine ~]# ll /data/backup/xtrabackup_dir/backup/
total 6362156
-rw-r 1 root root 515 Oct 12 18:01 backup-my.cnf
-rw-r 1 root root 2147483648 Oct 14 15:32 ibdata1
-rw-r 1 root root 2147483648 Oct 14 15:32 ib_logfile0 # 發現多了ib_logfile0和ib_logfile1文件
-rw-r 1 root root 2147483648 Oct 14 15:32 ib_logfile1
-rw-r 1 root root 12582912 Oct 14 15:32 ibtmp1 # 多了ibtmp1文件
drwxr-x--- 2 root root 6 Oct 14 15:32 #innodb_temp # 多了一個目錄
drwxr-x--- 2 root root 143 Oct 12 18:01 mysql
-rw-r 1 root root 231 Oct 12 18:01 mysql-bin.000023
-rw-r 1 root root 52 Oct 12 18:01 mysql-bin.index
-rw-r 1 root root 24117248 Oct 14 15:32 mysql.ibd
drwxr-x--- 2 root root 8192 Oct 12 18:01 performance_schema
drwxr-x--- 2 root root 44 Oct 12 18:00 sbtest
drwxr-x--- 2 root root 28 Oct 12 18:00 sys
drwxr-x--- 2 root root 20 Oct 12 18:00 test
-rw-r 1 root root 13631488 Oct 14 15:32 undo_001
-rw-r 1 root root 13631488 Oct 14 15:32 undo_002
-rw-r 1 root root 109 Oct 12 18:01 xtrabackup_binlog_info
-rw-r 1 root root 101 Oct 14 15:32 xtrabackup_checkpoints
-rw-r 1 root root 622 Oct 12 18:01 xtrabackup_info
-rw-r 1 root root 8388608 Oct 14 15:32 xtrabackup_logfile
-rw-r--r-- 1 root root 1 Oct 14 15:32 xtrabackup_master_key_id # 多了xtrabackup_master_key_id文件
-rw-r 1 root root 262 Oct 14 15:32 xtrabackup_tablespaces
[root@physical-machine ~]# xtrabackup --defaults-file=/etc/my.cnf --copy-back --target-dir=/data/backup/xtrabackup_dir/backup/
.
191014 16:26:10 [01] Creating directory ./#innodb_temp
191014 16:26:10 [01] ...done.
191014 16:26:10 completed OK!
# 修改目錄權限
[root@node4 backup]# chown mysql.mysql /data/mysqldata1/ -R
# 在my.cnf中配置好組複製的系統變量(如果是恢復故障Server而不是新增Server,這些配置都在,無需重複配置)
[root@node4 backup]# cat /etc/my.cnf
.
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
binlog_checksum=NONE
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "10.10.30.16:33061"
group_replication_group_seeds= "10.10.30.162:33061,10.10.30.163:33061,10.10.30.164:33061"
group_replication_bootstrap_group=off
report_host=node4
# 配置好hosts解析記錄,或者將report_host指定為IP位址也可以不用配置解析記錄(將node4的解析記錄同時配置到其他組成員的/etc/hosts文件中)(如果是恢復故障Server而不是新增Server,這些配置都在,無需重複配置)
[root@physical-machine ~]# cat /etc/hosts
.
10.10.30.16 node4
10.10.30.162 node1
10.10.30.163 node2
10.10.30.164 node3
# 操作命令類似如下
[root@node2 ~]# cp -ar /data/backup/{auto.cnf,mysqld-auto.cnf} /data/mysqldata1/mydata/
[root@physical-machine backup]# service mysqld start
Starting MySQL.... SUCCESS!
[root@node4 backup]# ps aux |grep mysqld |grep -v grep
root 27818 0.7 0.0 11760 1640 pts/3 S 17:23 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/home/mysql/data/mysqldata1/mydata --pid-file=/home/mysql/data/mysqldata1/sock/mysql.pid
mysql 29388 102 3.4 107051036 8436648 pts/3 Sl 17:23 0:16 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/home/mysql/data/mysqldata1/mydata --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/home/mysql/data/mysqldata1/log/error.log --open-files-limit=65535 --pid-file=/home/mysql/data/mysqldata1/sock/mysql.pid --socket=/home/mysql/data/mysqldata1/sock/mysql.sock --port=3306
[root@physical-machine ~]# cd /data/backup/xtrabackup_dir/backup/
# 記錄下320675e6-de7b-11e9-b3a9-5254002a54f2:1-4,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2771494字符串,稍後登錄資料庫中需要使用
[root@physical-machine backup]# cat xtrabackup_binlog_info
mysql-bin.000023 231 320675e6-de7b-11e9-b3a9-5254002a54f2:1-4,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2771494
# 先查看一下當前的GTID SET信息,如果與xtrabackup_binlog_info文件中記錄的一致,就不需要後續步驟了(在一個在線的組中,這裡GTID經常會不一致,這裡我們的示例中GTID SET碰巧一致是因為在執行備份期間,組並沒有新的請求進入)
admin@localhost : (none):37: > show master status;
+---++----+---++
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---++----+---++
| mysql-bin.000024 | 231 | | | 320675e6-de7b-11e9-b3a9-5254002a54f2:1-4,
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2771494 |
+---++----+---++
1 row in set (0.00 sec)
# 如果發現GTID SET信息與xtrabackup_binlog_info文件中記錄的不一樣,則需要執行後續步驟,重設GTID SET為xtrabackup_binlog_info文件中記錄的GTID SET
admin@localhost : (none):37: > reset master;
Query OK, 0 rows affected (0.01 sec)
admin@localhost : (none):38: > set global gtid_purged='320675e6-de7b-11e9-b3a9-5254002a54f2:1-4,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2771494';
Query OK, 0 rows affected (0.00 sec)
admin@localhost : (none):38: > show master status;
+---++----+---++
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---++----+---++
| mysql-bin.000001 | 151 | | | 320675e6-de7b-11e9-b3a9-5254002a54f2:1-4,
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2771494 |
+---++----+---++
1 row in set (0.00 sec)
# 使用如下語句使node4加入組
admin@localhost : (none):38: > START GROUP_REPLICATION;
Query OK, 0 rows affected (3.77 sec)
# 稍後查看成員狀態信息,可以看到node4節點已經處於ONLINE狀態了(如果在node4操作過程中,組持續不斷有新的事務寫入,那麼,在其申請加入組的過程中,會有一部分事務需要追趕,所以node4可能有一段時間處於RECOVERING狀態,等待追趕事務完成之後,才會變更ONLINE狀態)
admin@localhost : (none):02: > select * from performance_schema.replication_group_members;
+--+---+---+---+----+---+-+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+--+---+---+---+----+---+-+
| group_replication_applier | 2d283e92-de7b-11e9-a14d-525400c33752 | node2 | 3306 | ONLINE | SECONDARY | 8.0.17 |
| group_replication_applier | 2e33b2a7-de7b-11e9-9a21-525400bdd1f2 | node3 | 3306 | ONLINE | SECONDARY | 8.0.17 |
| group_replication_applier | 320675e6-de7b-11e9-b3a9-5254002a54f2 | node1 | 3306 | ONLINE | PRIMARY | 8.0.17 |
| group_replication_applier | 54b857f4-ee64-11e9-ada9-0025905b06da | node4 | 3306 | ONLINE | SECONDARY | 8.0.17 |
+--+---+---+---+----+---+-+
4 rows in set (0.01 sec)
[root@node4 ~]# cat my.cnf
.
# 不自動啟動MGR插件
group_replication_start_on_boot=OFF
# 在啟動故障主要節點的資料庫進程之前,設置只讀,防止在執行分布式恢復過程中,應用程式寫入新的數據到該節點中,造成與組中的數據不一致而導致加入組失敗
super_read_only=ON
# 如果有使用事件調度器做一些數據操作,也需要在啟動之前關閉,以防止造成數據不一致而加入組失敗
event_scheduler=OFF
# 動態啟用事件調度器
mysql> SET global event_scheduler=ON;
# 在my.cnf配置文件中啟用MGR插件和事件調度器,刪除只讀操作參數(注意,這裡不是將只讀參數設置為OFF,組複製會在組中根據單主和多主模式自動調整隻讀參數的設置,前面添加該參數到配置文件中的目的是為了避免發生意外寫入,一旦加入組之後,就不需要人為幹預了)
group_replication_start_on_boot=ON
event_scheduler=ON
PS:
xtrabackup 8.0版本支持備份時不加全局讀鎖(不執行FLUSH TABLE WITH READ LOCK語句),這就避免了在組複製中啟用多線程回放的組成員上執行備份時造成鎖死的現象,但是,為了保證一致性,是通過執行FLUSH NO_WRITE_TO_BINLOG BINARY LOGS語句來切換二進位日誌,並拷貝最後一個二進位日誌,在執行恢復時使用最後一個二進位日誌來恢復一致性位置的方式來變相實現的。如果有大事務,則存在無法切換二進位日誌的風險(執行切換二進位日誌的語句可能會被長時間阻塞),具體情況請大家自行斟酌,做好充足的測試。
在xtrabackup 8.0版本廢棄了innobackupex命令,統一使用xtrabackup命令,這樣一來,就可以使用xtrabackup命令的--lock-ddl和--lock-ddl-per-table選項在備份過程中阻塞DDL但並不阻塞DML操作。從而很好地防止了在備份期間發生DDL修改表結構導致備份失敗的問題。
在xtrabackup 8.0版本中,當發現有非InnoDB或RocksDB引擎時,Oracle MySQL版本則仍然會加全局讀鎖(由於Percona Server支持備份鎖,因此在這種情況下,Percona Server並不是加全局讀鎖,而是使用LOCK TABLES FOR BACKUP語句加備份鎖),當發現不存在非InnoDB或RocksDB引擎時,則如果無需考慮在備份期間存在DDL操作的情況,無需使用--lock-ddl和--lock-ddl-per-table選項,且備份過程中不會對資料庫執行加鎖操作。
羅小波·資料庫技術專家《千金良方——MySQL性能優化金字塔法則》、《數據生態:MySQL複製技術與生產實踐》作者之一。熟悉MySQL體系結構,擅長資料庫的整體調優,喜好專研開源技術,並熱衷於開源技術的推廣,在線上線下做過多次公開的資料庫專題分享,發表過近100篇資料庫相關的研究文章。全文完。
Enjoy MySQL 8.0 :)
葉老師的「MySQL核心優化」大課已升級到MySQL 8.0,掃碼開啟MySQL 8.0修行之旅吧