1、背景
MGR(MySQL Group Replication)是MySQL官方在5.7.17版本引進(jìn)的一個(gè)數(shù)據(jù)庫(kù)高可用與高擴(kuò)展的解決方案,以插件形式提供,實(shí)現(xiàn)了分布式下數(shù)據(jù)的最終已執(zhí)行,總結(jié)MGR的特點(diǎn)如下:
- 高一致性:基于分布式paxos協(xié)議實(shí)現(xiàn)組復(fù)制,保證數(shù)據(jù)一致性
- 高容錯(cuò)性:自動(dòng)檢測(cè)機(jī)制,只要不是大多數(shù)節(jié)點(diǎn)都宕機(jī)就可以繼續(xù)工作,內(nèi)置防腦裂保護(hù)機(jī)制;
- 高擴(kuò)展性:節(jié)點(diǎn)的添加與移除會(huì)自動(dòng)更新組成員信息,新節(jié)點(diǎn)加入后,自動(dòng)從其他節(jié)點(diǎn)同步增量數(shù)據(jù),知道與其他節(jié)點(diǎn)數(shù)據(jù)一致;
- 高靈活性:提供單住和多主模式,單主模式在主庫(kù)宕機(jī)后能夠自動(dòng)選主,所有寫(xiě)入都在主節(jié)點(diǎn)進(jìn)行,多主模式支持多節(jié)點(diǎn)寫(xiě)入。
2、環(huán)境
操作系統(tǒng):CentOS 7
數(shù)據(jù)庫(kù)版本:5.7.22
主機(jī)1:192.168.106.203
主機(jī)2:192.168.106.204
主機(jī)3:192.168.106.205
3、搭建步驟
3.1 數(shù)據(jù)庫(kù)安裝部署步驟,略
3.2 分別將主機(jī)的ip做映射
由于在集群中的merber_host中的值不能相同,所以需要做映射,當(dāng)然不做也可以,后面提到如何設(shè)置
3.3 開(kāi)始搭建集群節(jié)點(diǎn)一(主機(jī)1)
3.3.1 修改第一個(gè)節(jié)點(diǎn)的配置文件,內(nèi)容添加如下:
# replication param
# server-id,組內(nèi)唯一ID,不可重復(fù),一般配置為IP的后幾位
server_id = 203
# 開(kāi)啟二進(jìn)制日志
log_bin = mysql-bin
# 開(kāi)啟gtid模式
gtid_mode = on
enforce_gtid_consistency = 1
# 開(kāi)啟存儲(chǔ)從主庫(kù)接收來(lái)的二進(jìn)制日志
log_slave_updates = 1
# 設(shè)置二進(jìn)制日志格式為row
binlog_format = row
# group replication param
#復(fù)制元數(shù)據(jù)存入系統(tǒng)表
master_info_repository = table
#復(fù)制元數(shù)據(jù)存入系統(tǒng)表
relay_log_info_repository = table
#禁用二進(jìn)制日志時(shí)間校驗(yàn)和
binlog_checksum = none
#server必須為每個(gè)事物
transaction_write_set_extraction=XXHASH64
# 復(fù)制組的名字,可以隨意起,但一定要遵循gtid的格式
loose-group_replication_group_name='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
#插件在server啟動(dòng)時(shí)是否自動(dòng)啟動(dòng)組復(fù)制,如果不在配置文件中配置可在后面動(dòng)態(tài)配置
loose-group_replication_start_on_boot = off
#使用這個(gè)地址接收來(lái)自組中其他成員的傳入連接,一般為本機(jī)地址
loose-group_replication_local_address = '192.168.106.203:33061'
#組成員
loose-group_replication_group_seeds = '192.168.106.203:33061,192.168.106.204:33061,192.168.106.205:33061'
#是否為Group Replication的引導(dǎo)節(jié)點(diǎn),集群中第一個(gè)節(jié)點(diǎn)需要設(shè)置為ON來(lái)啟動(dòng)Group Replication,如果不在配置文件中配置可在后面動(dòng)態(tài)配置
loose-group_replication_bootstrap_group = off
# 一般配置為本機(jī)地址,也就是文中一開(kāi)頭說(shuō)的如果不做映射那么要配置這個(gè)
report_host = 192.168.106.203
report_port=3306
# 是否只有一個(gè)主可寫(xiě),設(shè)置為ON時(shí),其它節(jié)點(diǎn)不可寫(xiě),這個(gè)此處沒(méi)設(shè)置
group_replication_single_primary_mode = ON
3.3.2 重啟數(shù)據(jù)庫(kù)服務(wù)
# systemctl restart mysqld
3.3.3 登錄到數(shù)據(jù)庫(kù)
mysql > mysql -uroot -pyourpassword
3.3.4 關(guān)閉二進(jìn)制日志記錄功能
mysql > set sql_log_bin=0;
3.3.5 創(chuàng)建一個(gè)用于復(fù)制的用戶,不建議用root用戶
mysql > grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';
mysql > flush privileges;
3.3.6 開(kāi)啟二進(jìn)制日志記錄功能
mysql > set sql_sql_log_bin = 1;
3.3.7 設(shè)置使用組復(fù)制的用戶
mysql > change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';
3.3.8 安裝組復(fù)制插件
mysql > install PLUGIN group_replication SONAME 'group_replication.so';
3.3.9 開(kāi)啟插件自動(dòng)引用組功能
mysql > set global group_replication_bootstrap_group = ON;
3.3.10 開(kāi)啟組復(fù)制
mysql > start group_replication;
3.3.11 關(guān)閉插件自動(dòng)引用組功能
mysql > set global group_replication_bootstrap_group = OFF;
3.3.12 查看組內(nèi)節(jié)點(diǎn)和節(jié)點(diǎn)狀態(tài)
查看組內(nèi)成員
.mysql > select * from performance_schema.replication_group_members;

如果member_state顯示為online則為成功
具體說(shuō)明見(jiàn)另附
查看節(jié)點(diǎn)狀態(tài)
select * from performance_schema.replication_group_member_stats \G;

3.4 搭建第二個(gè)節(jié)點(diǎn)(主機(jī):192.168.106.204)
3.4.1 修改配置文件,
除了一下三項(xiàng)之外其他配置與節(jié)點(diǎn)一的一致(當(dāng)然部分配置可以根據(jù)實(shí)際情況調(diào)整)
server_id = 203
loose-group_replication_local_address = '192.168.106.204:33061'
report_host = 192.168.106.204
3.4.2 重啟數(shù)據(jù)庫(kù)服務(wù)
# systemctl restart mysqld
3.4.3 登錄到數(shù)據(jù)庫(kù)
mysql > mysql -uroot -pyourpassword
3.4.4 關(guān)閉二進(jìn)制日志記錄功能
mysql > set sql_log_bin=0;
3.4.5 創(chuàng)建一個(gè)用于復(fù)制的用戶,不建議用root用戶
mysql > grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';
mysql > flush privileges;
3.4.6 開(kāi)啟二進(jìn)制日志記錄功能
mysql > set sql_sql_log_bin = 1;
3.4.7 設(shè)置使用組復(fù)制的用戶
mysql > change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';
3.4.8 安裝組復(fù)制插件
mysql > install PLUGIN group_replication SONAME 'group_replication.so';
3.4.9 除了第一個(gè)節(jié)點(diǎn),其他節(jié)點(diǎn)都需要執(zhí)行這命令
mysql > set global group_replication_allow_local_disjoint_gtids_join = ON;
3.4.10 開(kāi)啟組復(fù)制
mysql > start group_replication;
3.4.11 查看成員信息:
mysql > select * from performance_schema.replication_group_members;

3.4.12 查看節(jié)點(diǎn)信息:
mysql > select * from performance_schema.replication_group_member_stats;

3.5 節(jié)點(diǎn)三的配置方式與節(jié)點(diǎn)二的配置方式相同
3.5.1 查看成員信息:
mysql > select * from performance_schema.replication_group_members;

3.5.2 查看節(jié)點(diǎn)信息:
mysql > select * from performance_schema.replication_group_member_stats \G

測(cè)試步驟:
在主庫(kù)上創(chuàng)建一個(gè)庫(kù),然后創(chuàng)建表,在兩個(gè)從庫(kù)上查詢數(shù)據(jù)是否同步?
兩個(gè)從庫(kù)只能執(zhí)行查詢操作?
手動(dòng)關(guān)閉主庫(kù),確認(rèn)兩個(gè)從庫(kù)其中一個(gè)是否會(huì)變成主庫(kù)?而且是MEMBER_ID第一個(gè)字母按優(yōu)先級(jí)排列的接管主庫(kù)?
常用命令:
查看成員信息:
mysql > select * from performance_schema.replication_group_members;
查看節(jié)點(diǎn)信息:
mysql > select * from performance_schema.replication_group_member_stats \G
查看主節(jié)點(diǎn):
mysql > select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member';
查看主節(jié)點(diǎn)方式2:
select @@read_only;
正常情況下且是在單主的情況下,從節(jié)點(diǎn)都是不可寫(xiě)的,即該參數(shù)的值為1,而主節(jié)點(diǎn)的值為0
4、多主模式切換
切換為多主
MGR切換模式需要重新啟動(dòng)組復(fù)制,因些需要在所有節(jié)點(diǎn)上先關(guān)閉組復(fù)制,設(shè)置 group_replication_single_primary_mode=OFF 等參數(shù),再啟動(dòng)組復(fù)制。
# 停止組復(fù)制(所有節(jié)點(diǎn)執(zhí)行):
mysql> stop group_replication;
mysql> set global group_replication_single_primary_mode=OFF;
mysql> set global group_replication_enforce_update_everywhere_checks=ON;
# 隨便選擇某個(gè)節(jié)點(diǎn)執(zhí)行
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
# 其他節(jié)點(diǎn)執(zhí)行
mysql> START GROUP_REPLICATION;
# 查看組信息,所有節(jié)點(diǎn)的 MEMBER_ROLE 都為 PRIMARY
mysql> SELECT * FROM performance_schema.replication_group_members;
切換回單主
# 所有節(jié)點(diǎn)執(zhí)行
mysql> stop group_replication;
mysql> set global group_replication_enforce_update_everywhere_checks=OFF;
mysql> set global group_replication_single_primary_mode=ON;
# 主節(jié)點(diǎn)(如主機(jī)1)執(zhí)行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
# 從節(jié)點(diǎn)(主機(jī)2、主機(jī)3)執(zhí)行
START GROUP_REPLICATION;
# 查看MGR組信息
mysql> SELECT * FROM performance_schema.replication_group_members;
5、搭建時(shí)遇到的問(wèn)題
5.1 在執(zhí)行change master的時(shí)候報(bào)錯(cuò)
ERROR 3077 (HY000): To have multiple channels, repository cannot be of type FILE; Please check the repository configuration and convert them to TABLE.
解決方法:
從庫(kù)需要master-info-repository、relay-log-info-repository設(shè)置為table
5.2 如果節(jié)點(diǎn)曾經(jīng)做過(guò)從庫(kù),那么在開(kāi)啟組復(fù)制的時(shí)候會(huì)報(bào)錯(cuò),且日志中會(huì)出現(xiàn)以下錯(cuò)誤:
[ERROR] Plugin group_replication reported: 'Can't start group replication on secondary member with single primary-mode while asynchronous replication channels are running
解決方法:
1、停止該節(jié)點(diǎn)的主從:stop slave;
2、建議刷新日志(生產(chǎn)環(huán)境慎用),reset master;reset slave;
6、附
6.1 MySQL Group Replication 節(jié)點(diǎn)狀態(tài):
CHANNEL_NAME : 顯示的值永遠(yuǎn)為group_replication_applier
MEMBER_ID : 節(jié)點(diǎn)serer_uuid
MEMBER_PORT : 節(jié)點(diǎn)服務(wù)端口,取值為server_port指定的端口
MEMBER_HOST : 如果沒(méi)有配置report_host選項(xiàng),那么取值為機(jī)器的hostname,可以通過(guò)report_host配置指定具體的IP
MEMBER_STATE : 節(jié)點(diǎn)狀態(tài)
MEMBER_STATE字段顯示當(dāng)前節(jié)點(diǎn)的狀態(tài),根據(jù)官方文檔,取值和介紹如下所示:
| 取值 | 解釋 | 狀態(tài)是否在集群內(nèi)同步 |
|---|---|---|
| ONLINE | 表示該節(jié)點(diǎn)可正常提供服務(wù) | YES |
| RECOVERING | 表示當(dāng)前節(jié)點(diǎn)正在從其他節(jié)點(diǎn)恢復(fù)數(shù)據(jù) | YES |
| OFFLINE | 表示GR插件已經(jīng)加載,但是該節(jié)點(diǎn)不屬于任何一個(gè)GR組 | NO |
| ERROR | 表示節(jié)點(diǎn)在recovery階段出現(xiàn)錯(cuò)誤或者從其他節(jié)點(diǎn)同步狀態(tài)中出現(xiàn)錯(cuò)誤 | NO |
| UNREACHABLE | 節(jié)點(diǎn)處于不可達(dá)狀態(tài),無(wú)法與之發(fā)生網(wǎng)絡(luò)通訊 | NO |
從上表可以知道,只有ONLINE和RECOVERING兩種狀態(tài)會(huì)在集群中得到同步。這個(gè)狀態(tài)同步是指狀態(tài)在所有節(jié)點(diǎn)上面查詢均能保持一致的意思。至于OFFLINE,ERROR和UNREABLE,做以下說(shuō)明:
只有在當(dāng)前OFFLINE節(jié)點(diǎn)查詢r(jià)eplication_group_members表才能得到OFFLINE狀態(tài),在其他節(jié)點(diǎn)上查詢r(jià)eplication_group_members表,則一般沒(méi)有該節(jié)點(diǎn)的狀態(tài)(很好理解,因?yàn)镺FFLINE節(jié)點(diǎn)已經(jīng)不屬于這個(gè)GR組了)
只有在當(dāng)前ERROR節(jié)點(diǎn)查詢r(jià)eplication_group_members表才能得到ERROR狀態(tài),同上面的OFFLINE,在其他節(jié)點(diǎn)上查詢也看不到該節(jié)點(diǎn)
假設(shè)節(jié)點(diǎn)A與B網(wǎng)絡(luò)通訊失敗,那么在節(jié)點(diǎn)A上查詢r(jià)eplication_group_members表,有可能得到B的狀態(tài)為UNREACHABLE